READ THE DATA

library(dplyr)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(data.table)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
data.table 1.12.8 using 4 threads (see ?getDTthreads).  Latest news: r-datatable.com

Attaching package: ‘data.table’

The following objects are masked from ‘package:dplyr’:

    between, first, last
library(mltools)
chicago_crime <- read.table(file = "chicago_crime_clean.csv", #Name of text file.
                      sep = ",",                       #Separation character.
                      header = TRUE,                   #If column names are in the first row.
                      na.strings = "NA",               #Character to be marked as missing value.
                      stringsAsFactors = FALSE)

chicago_crime$location_description <- (gsub(","," ",chicago_crime$location_description))
chicago_crime$description <- gsub(":=","",chicago_crime$description)
chicago_crime$description <- gsub(":","",chicago_crime$description)
chicago_crime$description <- gsub("MANU/POSS. W/","",chicago_crime$description)
chicago_crime$description <- gsub(",","",chicago_crime$description)
#chicago_crime$description <- gsub(".","",chicago_crime$description)
chicago_crime$location_description <- gsub("(E.G.  UBER  LYFT)","",chicago_crime$location_description)
chicago_crime$location_description <- gsub(",","",chicago_crime$location_description)
#chicago_crime$location_description <- gsub(".","",chicago_crime$location_description)

chicago_crime <- chicago_crime %>%
    dplyr::mutate(year = lubridate::year(date), 
                month = lubridate::month(date), 
                day = lubridate::day(date))
chicago_crime <- na.omit(chicago_crime)
chicago_crime <- select(chicago_crime,-c(X,unique_key, x_coordinate, y_coordinate, location, domestic, fbi_code, date,year))
chicago_crime$district <- factor(chicago_crime$district)

unique(chicago_crime$primary_type)
 [1] "ASSAULT"                           "OTHER OFFENSE"                     "NARCOTICS"                        
 [4] "DECEPTIVE PRACTICE"                "CRIMINAL TRESPASS"                 "WEAPONS VIOLATION"                
 [7] "CRIM SEXUAL ASSAULT"               "BURGLARY"                          "MOTOR VEHICLE THEFT"              
[10] "KIDNAPPING"                        "PUBLIC PEACE VIOLATION"            "INTERFERENCE WITH PUBLIC OFFICER" 
[13] "BATTERY"                           "GAMBLING"                          "ROBBERY"                          
[16] "OFFENSE INVOLVING CHILDREN"        "SEX OFFENSE"                       "THEFT"                            
[19] "CONCEALED CARRY LICENSE VIOLATION" "CRIMINAL DAMAGE"                   "ARSON"                            
[22] "HOMICIDE"                          "LIQUOR LAW VIOLATION"              "STALKING"                         
[25] "INTIMIDATION"                      "PROSTITUTION"                      "HUMAN TRAFFICKING"                
[28] "OBSCENITY"                         "OTHER NARCOTIC VIOLATION"          "PUBLIC INDECENCY"                 
[31] "NON-CRIMINAL"                     
head(chicago_crime)
summary(chicago_crime)
 case_number           block           primary_type       description        location_description    arrest             district     
 Length:213687      Length:213687      Length:213687      Length:213687      Length:213687        Length:213687      11     : 14869  
 Class :character   Class :character   Class :character   Class :character   Class :character     Class :character   18     : 14243  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character     Mode  :character   1      : 14227  
                                                                                                                     6      : 12717  
                                                                                                                     8      : 12577  
                                                                                                                     12     : 11592  
                                                                                                                     (Other):133462  
      ward          latitude       longitude          month             day      
 Min.   : 1.00   Min.   :36.62   Min.   :-91.69   Min.   : 1.000   Min.   : 1.0  
 1st Qu.:10.00   1st Qu.:41.77   1st Qu.:-87.71   1st Qu.: 4.000   1st Qu.: 8.0  
 Median :24.00   Median :41.87   Median :-87.66   Median : 7.000   Median :15.0  
 Mean   :23.83   Mean   :41.85   Mean   :-87.67   Mean   : 6.575   Mean   :15.5  
 3rd Qu.:36.00   3rd Qu.:41.91   3rd Qu.:-87.63   3rd Qu.: 9.000   3rd Qu.:23.0  
 Max.   :50.00   Max.   :42.02   Max.   :-87.52   Max.   :12.000   Max.   :31.0  
                                                                                 

Read the training set

library(dplyr)
library(data.table)
library(mltools)
chicago_crime_tr <- read.table(file = "chicago_crime_tr.csv", #Name of text file.
                      sep = ",",                       #Separation character.
                      header = TRUE,                   #If column names are in the first row.
                      na.strings = "NA",               #Character to be marked as missing value.
                      stringsAsFactors = FALSE)

chicago_crime_tr$location_description <- (gsub(","," ",chicago_crime_tr$location_description))
chicago_crime_tr$description <- gsub(":=","",chicago_crime_tr$description)
chicago_crime_tr$description <- gsub(":","",chicago_crime_tr$description)
chicago_crime_tr$description <- gsub("MANU/POSS. W/","",chicago_crime_tr$description)
chicago_crime_tr$description <- gsub(",","",chicago_crime_tr$description)
#chicago_crime$description <- gsub(".","",chicago_crime$description)
chicago_crime_tr$location_description <- gsub("(E.G.  UBER  LYFT)","",chicago_crime_tr$location_description)
chicago_crime_tr$location_description <- gsub(",","",chicago_crime_tr$location_description)
#chicago_crime$location_description <- gsub(".","",chicago_crime$location_description)

chicago_crime_tr <- chicago_crime_tr %>%
    dplyr::mutate(year = lubridate::year(date), 
                month = lubridate::month(date), 
                day = lubridate::day(date))

chicago_crime_tr <- select(chicago_crime_tr,-c(X,unique_key, x_coordinate, y_coordinate, location, domestic, fbi_code, date,year))

chicago_crime_tr <- na.omit(chicago_crime_tr)
chicago_crime_tr$district <- factor(chicago_crime_tr$district)

unique(chicago_crime_tr$primary_type)
 [1] "INTERFERENCE WITH PUBLIC OFFICER"  "OTHER OFFENSE"                     "DECEPTIVE PRACTICE"               
 [4] "SEX OFFENSE"                       "CRIM SEXUAL ASSAULT"               "BATTERY"                          
 [7] "CRIMINAL TRESPASS"                 "MOTOR VEHICLE THEFT"               "THEFT"                            
[10] "ASSAULT"                           "NARCOTICS"                         "ROBBERY"                          
[13] "PUBLIC PEACE VIOLATION"            "WEAPONS VIOLATION"                 "STALKING"                         
[16] "OFFENSE INVOLVING CHILDREN"        "ARSON"                             "BURGLARY"                         
[19] "CRIMINAL DAMAGE"                   "HOMICIDE"                          "INTIMIDATION"                     
[22] "KIDNAPPING"                        "HUMAN TRAFFICKING"                 "PROSTITUTION"                     
[25] "OBSCENITY"                         "CONCEALED CARRY LICENSE VIOLATION" "CRIMINAL SEXUAL ASSAULT"          
[28] "NON-CRIMINAL"                      "PUBLIC INDECENCY"                  "LIQUOR LAW VIOLATION"             
[31] "GAMBLING"                          "OTHER NARCOTIC VIOLATION"          "NON - CRIMINAL"                   
[34] "NON-CRIMINAL (SUBJECT SPECIFIED)" 
head(chicago_crime_tr)
summary(chicago_crime_tr)
 case_number           block           primary_type       description        location_description    arrest             district     
 Length:666666      Length:666666      Length:666666      Length:666666      Length:666666        Length:666666      11     : 45269  
 Class :character   Class :character   Class :character   Class :character   Class :character     Class :character   1      : 42067  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   Mode  :character     Mode  :character   18     : 41971  
                                                                                                                     8      : 41215  
                                                                                                                     6      : 37548  
                                                                                                                     12     : 35981  
                                                                                                                     (Other):422615  
      ward          latitude       longitude          month             day       
 Min.   : 1.00   Min.   :41.64   Min.   :-87.93   Min.   : 1.000   Min.   : 1.00  
 1st Qu.:11.00   1st Qu.:41.77   1st Qu.:-87.71   1st Qu.: 4.000   1st Qu.: 8.00  
 Median :24.00   Median :41.87   Median :-87.66   Median : 7.000   Median :16.00  
 Mean   :23.76   Mean   :41.85   Mean   :-87.67   Mean   : 6.594   Mean   :15.72  
 3rd Qu.:36.00   3rd Qu.:41.91   3rd Qu.:-87.63   3rd Qu.: 9.000   3rd Qu.:23.00  
 Max.   :50.00   Max.   :42.02   Max.   :-87.52   Max.   :12.000   Max.   :31.00  
                                                                                  
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "CRIMINAL TRESPASS"] <- "ROBBERY"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "BURGLARY"] <- "ROBBERY"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "MOTOR VEHICLE THEFT"] <- "THEFT"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "HOMICIDE"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "KIDNAPPING"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "BATTERY"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "INTIMIDATION"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "ARSON"] <- "VIOLENT CRIME"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "PROSTITUTION"] <- "SEX OFFENSE"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "CRIM SEXUAL ASSAULT"] <- "SEX OFFENSE"
chicago_crime_tr$primary_type[chicago_crime_tr$primary_type == "OTHER NARCOTIC VIOLATION"] <- "NARCOTICS"
chicago_crime_tr$primary_type <- factor(chicago_crime_tr$primary_type)

chicago_crime_subset_tr <- subset(chicago_crime_tr, primary_type=="ASSAULT" | primary_type == "VIOLENT CRIME" | primary_type == "THEFT" | primary_type=="NARCOTICS" | primary_type == "WEAPONS VIOLATION" | primary_type=="ROBBERY" | primary_type == "CRIMINAL DAMAGE" | primary_type == "DECEPTIVE PRACTICE" )

chicago_crime_subset_tr$primary_type <- factor(chicago_crime_subset_tr$primary_type)
chicago_crime_subset_tr <- na.omit(chicago_crime_subset_tr)
library(DataExplorer)
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
plot_str(chicago_crime_subset_tr)

plot_missing(chicago_crime_subset_tr)

#plot_histogram(chicago_crime_subset)
#plot_density(chicago_crime_subset)
#plot_correlation(chicago_numeric, type = 'continuous')
chicago_crime_subset_tr$month <- as.factor(chicago_crime_subset_tr$month)

plot_bar(chicago_crime_subset_tr)
4 columns ignored with more than 50 categories.
case_number: 610345 categories
block: 31746 categories
description: 210 categories
location_description: 162 categories

EXPLORATORY ANALYSIS

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.2.1     ✓ purrr   0.3.3
✓ tibble  2.1.3     ✓ stringr 1.4.0
✓ tidyr   1.0.2     ✓ forcats 0.4.0
✓ readr   1.3.1     
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x data.table::between() masks dplyr::between()
x dplyr::filter()       masks stats::filter()
x data.table::first()   masks dplyr::first()
x dplyr::lag()          masks stats::lag()
x data.table::last()    masks dplyr::last()
x tidyr::replace_na()   masks mltools::replace_na()
x purrr::transpose()    masks data.table::transpose()
ggplot(data = chicago_crime) +
  geom_bar(mapping = aes(x = primary_type)) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))


chicago_crime %>% 
  count(primary_type)

ggplot(data = chicago_crime) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1))


chicago_crime %>% 
  count(district)

ggplot(data = chicago_crime) +
  geom_bar(mapping = aes(x = arrest)) +
  theme(axis.text.x = element_text(hjust = 1))


chicago_crime %>% 
  count(arrest)

#chicago_crime$primary_type <- as.character(junk$nm)
chicago_crime$primary_type[chicago_crime$primary_type == "CRIMINAL TRESPASS"] <- "ROBBERY"
chicago_crime$primary_type[chicago_crime$primary_type == "BURGLARY"] <- "ROBBERY"
chicago_crime$primary_type[chicago_crime$primary_type == "MOTOR VEHICLE THEFT"] <- "THEFT"
chicago_crime$primary_type[chicago_crime$primary_type == "HOMICIDE"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "KIDNAPPING"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "BATTERY"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "INTIMIDATION"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "ARSON"] <- "VIOLENT CRIME"
chicago_crime$primary_type[chicago_crime$primary_type == "PROSTITUTION"] <- "SEX OFFENSE"
chicago_crime$primary_type[chicago_crime$primary_type == "CRIM SEXUAL ASSAULT"] <- "SEX OFFENSE"
chicago_crime$primary_type[chicago_crime$primary_type == "OTHER NARCOTIC VIOLATION"] <- "NARCOTICS"
chicago_crime$primary_type <- factor(chicago_crime$primary_type)

ggplot(data = chicago_crime) +
  geom_bar(mapping = aes(x = primary_type)) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))


chicago_crime %>% 
  count(primary_type)

chicago_crime_subset <- subset(chicago_crime, primary_type=="ASSAULT" | primary_type == "VIOLENT CRIME" | primary_type == "THEFT" | primary_type=="NARCOTICS" | primary_type == "WEAPONS VIOLATION" | primary_type=="ROBBERY" | primary_type == "CRIMINAL DAMAGE" | primary_type == "DECEPTIVE PRACTICE" )
chicago_crime_subset$primary_type <- factor(chicago_crime_subset$primary_type)
ggplot(data = chicago_crime_subset) +
  geom_bar(mapping = aes(x = primary_type)) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))


ggplot(data = chicago_crime_subset) +
  geom_count(mapping = aes(x = primary_type, y = district)) + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1))


ggplot(data = chicago_crime_subset) +
  geom_count(mapping = aes(x = arrest, y = primary_type)) + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1))


ggplot(data = chicago_crime_subset) +
  geom_count(mapping = aes(x = arrest, y = district)) + 
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

EXPLORATORY ANALYSIS BY CRIME

assault <- subset(chicago_crime_subset, primary_type=="ASSAULT")
violent_crime <- subset(chicago_crime_subset, primary_type=="VIOLENT CRIME")
theft <- subset(chicago_crime_subset, primary_type=="THEFT")
narcotics <- subset(chicago_crime_subset, primary_type=="NARCOTICS")
weapons_violation <- subset(chicago_crime_subset, primary_type=="WEAPONS VIOLATION")
robbery <- subset(chicago_crime_subset, primary_type=="ROBBERY")
criminal_damage <- subset(chicago_crime_subset, primary_type=="CRIMINAL DAMAGE")
deceptive_practice <- subset(chicago_crime_subset, primary_type=="DECEPTIVE PRACTICE")

assault_tr <- subset(chicago_crime_subset_tr, primary_type=="ASSAULT")
violent_tr_crime <- subset(chicago_crime_subset_tr, primary_type=="VIOLENT CRIME")
theft_tr <- subset(chicago_crime_subset_tr, primary_type=="THEFT")
narcotics_tr <- subset(chicago_crime_subset_tr, primary_type=="NARCOTICS")
weapons_violation_tr <- subset(chicago_crime_subset_tr, primary_type=="WEAPONS VIOLATION")
robbery_tr <- subset(chicago_crime_subset_tr, primary_type=="ROBBERY")
criminal_damage_tr <- subset(chicago_crime_subset_tr, primary_type=="CRIMINAL DAMAGE")
deceptive_practice_tr <- subset(chicago_crime_subset_tr, primary_type=="DECEPTIVE PRACTICE")

DISTRICTS

library(sqldf)
Loading required package: gsubfn
Loading required package: proto
unable to load shared object '/Library/Frameworks/R.framework/Resources/modules//R_X11.so':
  dlopen(/Library/Frameworks/R.framework/Resources/modules//R_X11.so, 6): Library not loaded: /opt/X11/lib/libSM.6.dylib
  Referenced from: /Library/Frameworks/R.framework/Resources/modules//R_X11.so
  Reason: image not foundCould not load tcltk.  Will use slower R code instead.
Loading required package: RSQLite
districts_true <- sqldf('SELECT district, AVG(latitude) as avg_latitude,AVG(longitude) as avg_longitude, count(*) as arrest FROM chicago_crime_subset WHERE arrest LIKE "True" GROUP BY district ORDER BY district')
districts_false <- sqldf('SELECT district, AVG(latitude) as avg_latitude,AVG(longitude) as avg_longitude, count(*) as no_arrest FROM chicago_crime_subset WHERE arrest LIKE "False" GROUP BY district ORDER BY district')
districts_true$arrest <- as.numeric(districts_true$arrest)
districts_false$no_arrest <- as.numeric(districts_false$no_arrest)
districts_true
districts_false

police_districts <- read.table(file = "Police_Stations.csv", #Name of text file.
                      sep = ",",                       #Separation character.
                      header = TRUE,                   #If column names are in the first row.
                      na.strings = "NA",               #Character to be marked as missing value.
                      stringsAsFactors = FALSE)
police_districts

police_districts$DISTRICT[police_districts$DISTRICT == "Headquarters"] <- "0"
police_districts$DISTRICT <- as.factor(police_districts$DISTRICT)

districts <- sqldf('SELECT DISTRICT as district, LATITUDE as latitude,LONGITUDE as longitude FROM police_districts')

arrest_percentage <- data.frame('District' = districts_false$district, 'PctArrest' = districts_true$arrest/(districts_true$arrest + districts_false$no_arrest), 'Crimes' = (districts_true$arrest + districts_false$no_arrest))
arrest_percentage

ggplot(data = arrest_percentage) +
  geom_col(mapping = aes(x = District, y = Crimes)) +
  geom_line(aes(x = District, y = PctArrest*10000, group = 1), color = "yellow") +
  scale_y_continuous(sec.axis = sec_axis(~./10000, name = "PctArrest")) +
  theme(axis.text.x = element_text(hjust = 1))


## INITIALIZE
library("leaflet")
library("data.table")
library("sp")
library("rgdal")
rgdal: version: 1.4-8, (SVN revision 845)
 Geospatial Data Abstraction Library extensions to R successfully loaded
 Loaded GDAL runtime: GDAL 2.4.2, released 2019/06/28
 Path to GDAL shared files: /Library/Frameworks/R.framework/Versions/3.6/Resources/library/rgdal/gdal
 GDAL binary built with GEOS: FALSE 
 Loaded PROJ.4 runtime: Rel. 5.2.0, September 15th, 2018, [PJ_VERSION: 520]
 Path to PROJ.4 shared files: /Library/Frameworks/R.framework/Versions/3.6/Resources/library/rgdal/proj
 Linking to sp version: 1.3-2 
# library("maptools")
library("KernSmooth")
KernSmooth 2.23 loaded
Copyright M. P. Wand 1997-2009
setDT(districts_false)

#devtools::install_github("dkahle/ggmap", ref = "tidyup", force = TRUE)
library(ggmap)
Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
Please cite ggmap if you use it! See citation("ggmap") for details.
chicago <- get_stamenmap(bbox = c(left = -88.0225, bottom = 41.5949, 
                                  right = -87.2713, top = 42.0677), 
                         zoom = 11)
Source : http://tile.stamen.com/terrain/11/523/759.png
Source : http://tile.stamen.com/terrain/11/524/759.png
Source : http://tile.stamen.com/terrain/11/525/759.png
Source : http://tile.stamen.com/terrain/11/526/759.png
Source : http://tile.stamen.com/terrain/11/527/759.png
Source : http://tile.stamen.com/terrain/11/523/760.png
Source : http://tile.stamen.com/terrain/11/524/760.png
Source : http://tile.stamen.com/terrain/11/525/760.png
Source : http://tile.stamen.com/terrain/11/526/760.png
Source : http://tile.stamen.com/terrain/11/527/760.png
Source : http://tile.stamen.com/terrain/11/523/761.png
Source : http://tile.stamen.com/terrain/11/524/761.png
Source : http://tile.stamen.com/terrain/11/525/761.png
Source : http://tile.stamen.com/terrain/11/526/761.png
Source : http://tile.stamen.com/terrain/11/527/761.png
Source : http://tile.stamen.com/terrain/11/523/762.png
Source : http://tile.stamen.com/terrain/11/524/762.png
Source : http://tile.stamen.com/terrain/11/525/762.png
Source : http://tile.stamen.com/terrain/11/526/762.png
Source : http://tile.stamen.com/terrain/11/527/762.png
Source : http://tile.stamen.com/terrain/11/523/763.png
Source : http://tile.stamen.com/terrain/11/524/763.png
Source : http://tile.stamen.com/terrain/11/525/763.png
Source : http://tile.stamen.com/terrain/11/526/763.png
Source : http://tile.stamen.com/terrain/11/527/763.png
ggmap(chicago) +
geom_text(aes(x = longitude, y = latitude, label = district), data = districts)


library(ggmap)
chicago <- get_stamenmap(bbox = c(left = -88.0225, bottom = 41.5949, 
                                  right = -87.2713, top = 42.0677), 
                         zoom = 11)
ggmap(chicago) +
geom_text(aes(x = LONGITUDE, y = LATITUDE, label = DISTRICT), data = police_districts)

ggplot(data = assault) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("ASSAULT BY DISTRICT")


ggplot(data = theft) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("THEFTS BY DISTRICT")


ggplot(data = violent_crime) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("VIOLENT CRIMES BY DISTRICT")


ggplot(data = narcotics) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("NARCOTIC CRIMES BY DISTRICT")


ggplot(data = weapons_violation) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("WEAPON-RELATED CRIMES BY DISTRICT")


ggplot(data = robbery) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("ROBBERIES BY DISTRICT")


ggplot(data = criminal_damage) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("CRIMINAL DAMAGE CRIMES BY DISTRICT")


ggplot(data = deceptive_practice) +
  geom_bar(mapping = aes(x = district)) +
  theme(axis.text.x = element_text(hjust = 1)) +
  ggtitle("DECEPTIVE PRACTICE CRIMES BY DISTRICT")

library(ggplot2)

ggplot(data = chicago_crime_subset, aes(x=primary_type, y=district, fill=arrest)) + 
  geom_tile() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

# Correlation
library(ggplot2)
ggplot(chicago_crime_subset,aes(x=district,y=primary_type,color=arrest))+geom_point(alpha=0.5)

Association Rules

chicago_crime_subset_2 <- subset(chicago_crime_subset, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
chicago_crime_subset_2 <- subset(chicago_crime_subset_2, select=-c(location_description))
write.csv(chicago_crime_subset_2,"chicago_crime_AR.csv", quote = FALSE, row.names = FALSE)
library(arules)
Loading required package: Matrix

Attaching package: ‘Matrix’

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack


Attaching package: ‘arules’

The following object is masked from ‘package:dplyr’:

    recode

The following objects are masked from ‘package:base’:

    abbreviate, write
crime_transactions <- read.transactions("chicago_crime_AR.csv", sep=",")

#deceptive_practice_2 <- subset(deceptive_practice, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#write.csv(deceptive_practice_2,"deceptive_practice.csv", quote = FALSE, row.names = FALSE)
#dp_transactions <- read.transactions("deceptive_practice.csv", sep=",")
if (!require("RColorBrewer")) {
  # install color package of R
  install.packages("RColorBrewer")
  #include library RColorBrewer
  library(RColorBrewer)
}
Loading required package: RColorBrewer
itemFrequencyPlot(crime_transactions,topN=20,type="absolute",
                  col=brewer.pal(8,'Pastel2'), 
                  main="Absolute Item Frequency Plot")

Reglas de Asociacion General

# Rule GENERATION
association.rules.clean <- apriori(crime_transactions, parameter = list(supp=0.001, conf=0.7))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [179 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
subset.rules.clean <- which(colSums(is.subset(association.rules.clean, association.rules.clean)) > 1)
subset.association.rules.clean. <- association.rules.clean[-subset.rules.clean]
inspect(subset.association.rules.clean.)

rules_by_count <- sort(association.rules.clean, by = "count")
rules_by_conf <- sort(association.rules.clean, by = "confidence")
rules_by_supp <- sort(association.rules.clean, by = "lift")
inspect(rules_by_count)
inspect(rules_by_conf)
inspect(rules_by_supp)
# Rule GENERATION
assault.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.001, conf=0.1),
                                   appearance = list(default="lhs",rhs="ASSAULT"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [7 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
assault.subset.rules <- which(colSums(is.subset(assault.association.rules, assault.association.rules)) > 1) # get subset rules in vector
assault.subset.association.rules. <- assault.association.rules[-assault.subset.rules] # remove subset rules.
inspect(assault.subset.association.rules.)

as_by_count <- sort(assault.association.rules, by = "count")
as_by_conf <- sort(assault.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(as_by_count)
inspect(as_by_conf)
#inspect(dp_by_supp)
# Rule GENERATION
cd.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.001, conf=0.1),
                                     appearance = list(default="lhs",rhs="CRIMINAL DAMAGE"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [40 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
cd.subset.rules <- which(colSums(is.subset(cd.association.rules, cd.association.rules)) > 1) # get subset rules in vector
cd.subset.association.rules. <- cd.association.rules[-cd.subset.rules] # remove subset rules.
inspect(cd.association.rules)

cd_by_count <- sort(cd.association.rules, by = "count")
cd_by_conf <- sort(cd.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(cd_by_count)
inspect(cd_by_conf)
#inspect(dp_by_supp)
# Rule GENERATION
dp.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.001, conf=0.1),
                                     appearance = list(default="lhs",rhs="DECEPTIVE PRACTICE"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [19 rule(s)] done [0.00s].
creating S4 object  ... done [0.05s].
# Borrar reglas redundantes
dp.subset.rules <- which(colSums(is.subset(dp.association.rules, dp.association.rules)) > 1) # get subset rules in vector
dp.subset.association.rules. <- dp.association.rules[-dp.subset.rules] # remove subset rules.
inspect(dp.subset.association.rules.)

dp_by_count <- sort(dp.subset.association.rules., by = "count")
dp_by_conf <- sort(dp.subset.association.rules., by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(dp_by_count)
inspect(dp_by_conf)
#inspect(dp_by_supp)
narcotics_clean.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.001, conf=0.1),
                                   appearance = list(default="lhs",rhs="NARCOTICS"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [18 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
narcotics_clean.subset.rules <- which(colSums(is.subset(narcotics_clean.association.rules, narcotics_clean.association.rules)) > 1) # get subset rules in vector
narcotics_clean.subset.association.rules. <- narcotics_clean.association.rules[-narcotics_clean.subset.rules] # remove subset rules.
inspect(narcotics_clean.subset.association.rules.)

narc_by_count <- sort(narcotics_clean.association.rules, by = "count")
narc_by_conf <- sort(narcotics_clean.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(narc_by_count)
inspect(narc_by_conf)
#inspect(dp_by_supp)
robbery.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.001, conf=0.15),
                                   appearance = list(default="lhs",rhs="ROBBERY"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [11 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
robbery.subset.rules <- which(colSums(is.subset(robbery.association.rules, robbery.association.rules)) > 1) 
robbery.subset.association.rules. <- robbery.association.rules[-robbery.subset.rules] # remove subset rules.
inspect(robbery.association.rules)

rob_by_count <- sort(robbery.association.rules, by = "count")
rob_by_conf <- sort(robbery.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(rob_by_count)
inspect(rob_by_conf)
#inspect(dp_by_supp)
theft.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.005, conf=0.5),
                                   appearance = list(default="lhs",rhs="THEFT"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 972 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [4 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
theft.subset.rules <- which(colSums(is.subset(theft.association.rules, theft.association.rules)) > 1) 
theft.subset.association.rules. <- theft.association.rules[-theft.subset.rules] # remove subset rules.
inspect(theft.subset.association.rules.)

theft_by_count <- sort(theft.association.rules, by = "count")
theft_by_conf <- sort(theft.association.rules, by = "confidence")
#dp_by_supp <- sort(dp.subset.association.rules., by = "support")
inspect(theft_by_count)
inspect(theft_by_conf)
#inspect(dp_by_supp)
vc.association.rules <- apriori(crime_transactions, parameter = 
                                     list(supp=0.001, conf=0.15),
                                   appearance = list(default="lhs",rhs="VIOLENT CRIME"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [21 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
vc.subset.rules <- which(colSums(is.subset(vc.association.rules, vc.association.rules)) > 1) # get subset rules in  
vc.subset.association.rules. <- vc.association.rules[-vc.subset.rules] # remove subset rules.
inspect(vc.subset.association.rules.)

vc_by_count <- sort(vc.association.rules, by = "count")
vc_by_conf <- sort(vc.association.rules, by = "confidence")
#vc_by_supp <- sort(vc.subset.association.rules., by = "support")
inspect(vc_by_count)
inspect(vc_by_conf)
#inspect(wv_by_supp)
wv.association.rules <- apriori(crime_transactions,parameter = 
                                      list(supp=0.001, conf=0.1),
                                      appearance = list(default="lhs",rhs="WEAPONS VIOLATION"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [8 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
wv.subset.rules <- which(colSums(is.subset(wv.association.rules, wv.association.rules)) > 1) # get subset rules in  
wv.subset.association.rules. <- wv.association.rules[-wv.subset.rules] # remove subset rules.
inspect(wv.subset.association.rules.)

wv_by_count <- sort(wv.association.rules, by = "count")
wv_by_conf <- sort(wv.association.rules, by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(wv_by_count)
inspect(wv_by_conf)
#inspect(wv_by_supp)
true.association.rules <- apriori(crime_transactions,parameter = 
                                      list(supp=0.001, conf=0.5),
                                      appearance = list(default="lhs",rhs="True"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [24 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
true.subset.rules <- which(colSums(is.subset(true.association.rules, true.association.rules)) > 1) # get subset rules in  
true.subset.association.rules. <- true.association.rules[-true.subset.rules] # remove subset rules.
inspect(true.subset.association.rules.)

t_by_count <- sort(true.subset.association.rules., by = "count")
t_by_conf <- sort(true.subset.association.rules., by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(t_by_count)
inspect(t_by_conf)
#inspect(wv_by_supp)
false.association.rules <- apriori(crime_transactions,parameter = 
                                      list(supp=0.001, conf=0.8),
                                      appearance = list(default="lhs",rhs="False"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 194 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.04s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.05s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [125 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
false.subset.rules <- which(colSums(is.subset(false.association.rules, false.association.rules)) > 1) # get subset rules in  
false.subset.association.rules. <- false.association.rules[-false.subset.rules] # remove subset rules.
inspect(false.subset.association.rules.)

f_by_count <- sort(false.association.rules, by = "count")
f_by_conf <- sort(false.association.rules, by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(f_by_count)
inspect(f_by_conf)
#inspect(wv_by_supp)
ocho.association.rules <- apriori(crime_transactions,parameter = 
                                      list(supp=0.0001, conf=0.01),
                                      appearance = list(default="lhs",rhs="8"))
Apriori

Parameter specification:

Algorithmic control:

Absolute minimum support count: 19 

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[36 item(s), 194542 transaction(s)] done [0.03s].
sorting and recoding items ... [32 item(s)] done [0.00s].
creating transaction tree ... done [0.04s].
checking subsets of size 1 2 3 done [0.00s].
writing ... [26 rule(s)] done [0.00s].
creating S4 object  ... done [0.02s].
# Borrar reglas redundantes
ocho.subset.rules <- which(colSums(is.subset(ocho.association.rules, ocho.association.rules)) > 1) # get subset rules in  
ocho.subset.association.rules. <- ocho.association.rules[-ocho.subset.rules] # remove subset rules.
inspect(ocho.subset.association.rules.)

ocho_by_count <- sort(ocho.association.rules, by = "count")
ocho_by_conf <- sort(ocho.association.rules, by = "confidence")
#wv_by_supp <- sort(wv.subset.association.rules., by = "support")
inspect(ocho_by_count)
inspect(ocho_by_conf)
#inspect(wv_by_supp)
## GRAFICOS 
## Dataset Entero
library(arulesViz)
Loading required package: grid
Registered S3 method overwritten by 'seriation':
  method         from 
  reorder.hclust gclus
# Filter rules with confidence greater than 0.4 or 40%
subRules<-association.rules.clean[quality(association.rules.clean)$confidence>0.7]
#Plot SubRules
plot(subRules,method="two-key plot")


## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(subRules, n = 25, by = "confidence")

# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(top10subRules, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules, n=25, by="confidence")
plot(subRules2, method="paracoord")

#Plot SubRules
plot(assault.subset.association.rules.,method="two-key plot")


## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(assault.subset.association.rules., n = 20, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(assault.subset.association.rules., method = "graph",  engine = "htmlwidget")


## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(assault.subset.association.rules., n=20, by="confidence")
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(cd.association.rules,method="two-key plot")


subRules_cd<-cd.association.rules[quality(cd.association.rules)$confidence>0.2]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(cd.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_cd, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_cd, n=25, by="confidence")
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(dp.association.rules,method="two-key plot")


subRules_dp<-dp.association.rules[quality(dp.association.rules)$confidence>0.1]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(dp.association.rules, n = 10, by = "count")

# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_dp, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_dp, n=25, by="count")
plot(subRules_dp, method="paracoord")

#Plot SubRules
plot(narcotics_clean.association.rules,method="two-key plot")


subRules_narcotics<-narcotics_clean.association.rules[quality(narcotics_clean.association.rules)$confidence>0.6]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(narcotics_clean.association.rules, n = 10, by = "confidence")

# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_narcotics, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_narcotics, n=25, by="confidence")
plot(subRules_narcotics, method="paracoord")

#Plot SubRules
plot(robbery.association.rules,method="two-key plot")


subRules_robbery<-robbery.association.rules[quality(robbery.association.rules)$confidence>0.15]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(robbery.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_robbery, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation Dataset Limpio
# Filter top 20 rules with highest lift
subRules2<-head(subRules_robbery, n=25, by="confidence")
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(theft.association.rules,method="two-key plot")


subRules_theft<-theft.association.rules[quality(theft.association.rules)$confidence>0.45]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(theft.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_theft, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(vc.association.rules,method="two-key plot")


subRules_vc<-vc.association.rules[quality(vc.association.rules)$confidence>0.15]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(vc.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_vc, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(wv.association.rules,method="two-key plot")


subRules_wv<-wv.association.rules[quality(wv.association.rules)$confidence>0.1]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(wv.association.rules, n = 10, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_wv, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation
plot(top10subRules, method="paracoord")

#Plot SubRules
plot(ocho.association.rules,method="two-key plot")


subRules_8<-ocho.association.rules[quality(ocho.association.rules)$confidence>0.01]

## Seleccionamos un numero limitado de reglas en el dataset limpio
top10subRules <- head(ocho.association.rules, n = 20, by = "confidence")
inspect(top10subRules)
# Now, plot an interactive graph:
#Note: You can make all your plots interactive using engine=htmlwidget parameter in plot
plot(subRules_8, method = "graph",  engine = "htmlwidget")


## Individual Rule Representation
plot(top10subRules, method="paracoord")

Mapas de Densidad

## INITIALIZE
library("leaflet")
library("data.table")
library("sp")
library("rgdal")
# library("maptools")
library("KernSmooth")
library(viridis)
Loading required package: viridisLite
library(RColorBrewer)

assault <- na.omit(assault)
setDT(assault)
criminal_damage <- na.omit(criminal_damage)
setDT(criminal_damage)
deceptive_practice <- na.omit(deceptive_practice)
setDT(deceptive_practice)
narcotics <- na.omit(narcotics)
setDT(narcotics)
robbery <- na.omit(robbery)
setDT(robbery)
theft <- na.omit(theft)
setDT(theft)
violent_crime <- na.omit(violent_crime)
setDT(violent_crime)
weapons_violation <- na.omit(weapons_violation)
setDT(weapons_violation)

## MAKE CONTOUR LINES
## Assault
kde_assault <- bkde2D(assault[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_assault <- contourLines(kde_assault$x1 , kde_assault$x2 , kde_assault$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_assault<- as.factor(sapply(CL_assault, `[[`, "level"))
NLEV_assault <- length(levels(LEVS_assault))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_assault <- lapply(1:length(CL_assault), function(i)
    Polygons(list(Polygon(cbind(CL_assault[[i]]$x, CL_assault[[i]]$y))), ID=i))
spgons_assault = SpatialPolygons(pgons_assault)

## Criminal Damage
kde_cd <- bkde2D(criminal_damage[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_cd <- contourLines(kde_cd$x1 , kde_cd$x2 , kde_cd$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_cd<- as.factor(sapply(CL_cd, `[[`, "level"))
NLEV_cd <- length(levels(LEVS_cd))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_cd <- lapply(1:length(CL_cd), function(i)
    Polygons(list(Polygon(cbind(CL_cd[[i]]$x, CL_cd[[i]]$y))), ID=i))
less than 4 coordinates in polygonless than 4 coordinates in polygon
spgons_cd = SpatialPolygons(pgons_cd)

## Deceptive Practice
kde_dp <- bkde2D(deceptive_practice[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_dp <- contourLines(kde_dp$x1 , kde_dp$x2 , kde_dp$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_dp<- as.factor(sapply(CL_dp, `[[`, "level"))
NLEV_dp <- length(levels(LEVS_dp))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_dp <- lapply(1:length(CL_dp), function(i)
    Polygons(list(Polygon(cbind(CL_dp[[i]]$x, CL_dp[[i]]$y))), ID=i))
spgons_dp = SpatialPolygons(pgons_dp)

## Narcotics
kde_narcotics <- bkde2D(narcotics[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_narcotics <- contourLines(kde_narcotics$x1 , kde_narcotics$x2 , kde_narcotics$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_narcotics <- as.factor(sapply(CL_narcotics, `[[`, "level"))
NLEV_narcotics <- length(levels(LEVS_narcotics))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_narcotics <- lapply(1:length(CL_narcotics), function(i)
    Polygons(list(Polygon(cbind(CL_narcotics[[i]]$x, CL_narcotics[[i]]$y))), ID=i))
spgons_narcotics = SpatialPolygons(pgons_narcotics)

## Robbery
kde_robbery <- bkde2D(robbery[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_robbery <- contourLines(kde_robbery$x1 , kde_robbery$x2 , kde_robbery$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_robbery <- as.factor(sapply(CL_robbery, `[[`, "level"))
NLEV_robbery <- length(levels(LEVS_robbery))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_robbery <- lapply(1:length(CL_robbery), function(i)
    Polygons(list(Polygon(cbind(CL_robbery[[i]]$x, CL_robbery[[i]]$y))), ID=i))
spgons_robbery = SpatialPolygons(pgons_robbery)

## Thefts
kde_theft <- bkde2D(theft[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_theft <- contourLines(kde_theft$x1 , kde_theft$x2 , kde_theft$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_theft <- as.factor(sapply(CL_theft, `[[`, "level"))
NLEV_theft <- length(levels(LEVS_theft))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_theft <- lapply(1:length(CL_theft), function(i)
    Polygons(list(Polygon(cbind(CL_theft[[i]]$x, CL_theft[[i]]$y))), ID=i))
spgons_theft = SpatialPolygons(pgons_theft)

## Violent Crimws
kde_vc <- bkde2D(violent_crime[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_vc <- contourLines(kde_vc$x1 , kde_vc$x2 , kde_vc$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_vc <- as.factor(sapply(CL_vc, `[[`, "level"))
NLEV_vc <- length(levels(LEVS_vc))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_vc <- lapply(1:length(CL_vc), function(i)
    Polygons(list(Polygon(cbind(CL_vc[[i]]$x, CL_vc[[i]]$y))), ID=i))
spgons_vc = SpatialPolygons(pgons_vc)

## Weapons Violation
kde_wv <- bkde2D(weapons_violation[ , list(longitude, latitude)],
              bandwidth=c(.0001, .0001), gridsize = c(75,75))
Binning grid too coarse for current (small) bandwidth: consider increasing 'gridsize'
CL_wv <- contourLines(kde_wv$x1 , kde_wv$x2 , kde_wv$fhat)

## EXTRACT CONTOUR LINE LEVELS
LEVS_wv <- as.factor(sapply(CL_wv, `[[`, "level"))
NLEV_wv <- length(levels(LEVS_wv))

## CONVERT CONTOUR LINES TO POLYGONS
pgons_wv <- lapply(1:length(CL_wv), function(i)
    Polygons(list(Polygon(cbind(CL_wv[[i]]$x, CL_wv[[i]]$y))), ID=i))
less than 4 coordinates in polygon
spgons_wv = SpatialPolygons(pgons_wv)

leaflet() %>% addTiles() %>%
    addPolygons(data = spgons_narcotics, color = brewer.pal(NLEV_narcotics, name = "YlOrRd")[LEVS_narcotics], group = "Narcotics") %>%
    addPolygons(data = spgons_assault, color = brewer.pal(NLEV_assault, name = "Reds")[LEVS_assault], group = "Assault") %>%
    addPolygons(data = spgons_cd, color = brewer.pal(NLEV_cd, name="YlGnBu")[LEVS_cd], group = "Criminal Damage") %>%
    addPolygons(data = spgons_dp, color = brewer.pal(NLEV_dp, name = "YlGn")[LEVS_dp], group = "Deceptive Practice") %>%
    addPolygons(data = spgons_robbery, color = brewer.pal(NLEV_robbery, name = "Purples")[LEVS_robbery], group = "Robbery") %>%
    addPolygons(data = spgons_theft, color = brewer.pal(NLEV_theft, name = "Oranges")[LEVS_theft], group = "Thefts") %>%
    addPolygons(data = spgons_vc, color = brewer.pal(NLEV_vc, name = "Greys")[LEVS_vc], group = "Violent Crimes") %>%
    addPolygons(data = spgons_wv, color = brewer.pal(NLEV_wv, name = "Blues")[LEVS_wv], group = "Weapons Violation") %>%
    addLabelOnlyMarkers(districts$longitude, districts$latitude, label =  districts$district, 
                      labelOptions = labelOptions(noHide = T, direction = 'top', textOnly = T), group = "Districts") %>%
    addLayersControl(overlayGroups = c("Assault", "Criminal Damage","Deceptive Practice", "Narcotics","Robbery","Thefts","Violent Crimes","Weapons Violation", "Districts"),options = layersControlOptions(collapsed = FALSE))
n too large, allowed maximum for palette YlOrRd is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Reds is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette YlGnBu is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette YlGn is 9
Returning the palette you asked for with that many colors
n too large, allowed maximum for palette Greys is 9
Returning the palette you asked for with that many colors

    
#addCircles(lng = narcotics$longitude, lat = narcotics$latitude,radius = .1, opacity = .4, col = "blue", group = "Points") %>%
#leaflet() %>% addTiles() %>%
#    addCircles(lng = weapons_violation$longitude, lat = weapons_violation$latitude,radius = .05, opacity = 0.1, col = brewer.pal(10,name = "Reds"), group = "Narcotics") %>%
#    addLabelOnlyMarkers(districts$longitude, districts$latitude, label =  districts$district, 
#                      labelOptions = labelOptions(noHide = T, direction = 'top', textOnly = T, textsize = "15px"), group = #"Districts") %>%
#    addLayersControl(overlayGroups = c("Assault", "Criminal Damage","Deceptive Practice", "Narcotics","Robbery","Thefts","Violent Crimes","Weapons Violation", "Districts"),options = layersControlOptions(collapsed = FALSE))

Clustering

chicago_crime_clustering <- subset(chicago_crime_subset, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
unique(chicago_crime_clustering$primary_type)
[1] ASSAULT            NARCOTICS          DECEPTIVE PRACTICE ROBBERY            WEAPONS VIOLATION  THEFT              VIOLENT CRIME     
[8] CRIMINAL DAMAGE   
Levels: ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
library(data.table)
library(mltools)
#Crime_chicago_dummy <- one_hot(as.data.table(Crime_chicago_def_clust))

types <- unique(chicago_crime_clustering$primary_type)
chicago_crime_clustering$primary_type <- match(chicago_crime_clustering$primary_type, unique(chicago_crime_clustering$primary_type))
chicago_crime_clustering$arrest <- match(chicago_crime_clustering$arrest, unique(chicago_crime_clustering$arrest))
#chicago_crime_clustering$location_description <- match(chicago_crime_clustering$location_description, unique(chicago_crime_clustering$location_description))
chicago_crime_clustering$district <- as.numeric(chicago_crime_clustering$district)
test <- chicago_crime_clustering
#Normalization of variables
library(RSNNS)

train_set <- subset(chicago_crime_subset_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
train_set$primary_type <- match(train_set$primary_type, unique(train_set$primary_type))
train_set$arrest <- match(train_set$arrest, unique(train_set$arrest))
#train_set$location_description <- match(train_set$location_description, unique(train_set$location_description))
train_set$district <- as.numeric(train_set$district)

#index <- sample(nrow(chicago_crime_clustering_cut), round(0.75*nrow(chicago_crime_clustering_cut)))
#train <- Crime_chicago_def_clust_cut[index,] 
#test <- Crime_chicago_def_clust_cut[-index,]
train_label <- train_set[,1]
test_label <- test[,1]

#Optimum number of clusters. Elbow method
# Alternative using fviz function for Elbow method
library(factoextra)
library(NbClust)
set.seed(123)
train_small <- train_set[1:1000,]
test_small <- test[1:100,]

## Dendograms
library(tidyverse)      #data manipulation and visualization
library(class)          # to call class package for kNN
library(caret)
library(cluster)
# Divisive Hierarchical Clustering - diana
# compute divisive hierarchical clustering
div <- diana(train_small)
plot(div, main = "Divisive")


distance <- dist(train_small,method = "euclidean")
agg <- hclust(distance, method = "complete")
plot(agg,
     main = "Agglomerative, complete linkages")


library(fpc)
cstats.table <- function(dist, tree, k) {
clust.assess <- c("cluster.number","n","within.cluster.ss","average.within","average.between",
                  "wb.ratio","dunn2","avg.silwidth")
clust.size <- c("cluster.size")
stats.names <- c()
row.clust <- c()
output.stats <- matrix(ncol = k, nrow = length(clust.assess))
cluster.sizes <- matrix(ncol = k, nrow = k)
for(i in c(1:k)){
  row.clust[i] <- paste("Cluster-", i, " size")
}
for(i in c(2:k)){
  stats.names[i] <- paste("Test", i-1)
  
  for(j in seq_along(clust.assess)){
    output.stats[j, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.assess])[j]
    
  }
  
  for(d in 1:k) {
    cluster.sizes[d, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.size])[d]
    dim(cluster.sizes[d, i]) <- c(length(cluster.sizes[i]), 1)
    cluster.sizes[d, i]
    
  }
}
output.stats.df <- data.frame(output.stats)
cluster.sizes <- data.frame(cluster.sizes)
cluster.sizes[is.na(cluster.sizes)] <- 0
rows.all <- c(clust.assess, row.clust)
# rownames(output.stats.df) <- clust.assess
output <- rbind(output.stats.df, cluster.sizes)[ ,-1]
colnames(output) <- stats.names[2:k]
rownames(output) <- rows.all
is.num <- sapply(output, is.numeric)
output[is.num] <- lapply(output[is.num], round, 2)
output
}
# I am capping the maximum amout of clusters by 7
# I want to choose a reasonable number, based on which I will be able to see basic differences between customer groups as a result
stats.df.divisive <- cstats.table(distance, div, 7)
stats.df.divisive

stats.df.aggl <-cstats.table(distance, agg, 7) #complete linkages looks like the most balanced approach
stats.df.aggl

#confusionMatrix(train_small, )
library(data.table)
library(mltools)
#Crime_chicago_dummy <- one_hot(as.data.table(Crime_chicago_def_clust))
#narcotics <- subset(narcotics, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#narcotics_tr <- subset(narcotics_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
narcotics_clustering <- subset(narcotics, select=-c(location_description))
narcotics_clustering_tr <- subset(narcotics_tr, select=-c(location_description))

types <- unique(chicago_crime_clustering$primary_type)
narcotics_clustering$primary_type <- match(chicago_crime_clustering$primary_type, unique(chicago_crime_clustering$primary_type))
narcotics_clustering$arrest <- match(chicago_crime_clustering$arrest, unique(chicago_crime_clustering$arrest))
#narcotics_clustering$location_description <- match(chicago_crime_clustering$location_description, unique(narcotics_clustering$location_description))
narcotics_clustering$district <- as.numeric(narcotics_clustering$district)
test <- narcotics_clustering
#Normalization of variables
library(RSNNS)

train_set <- narcotics_clustering_tr
train_set$primary_type <- match(train_set$primary_type, unique(train_set$primary_type))
train_set$arrest <- match(train_set$arrest, unique(train_set$arrest))
#train_set$location_description <- match(train_set$location_description, unique(train_set$location_description))
train_set$district <- as.numeric(train_set$district)

#index <- sample(nrow(chicago_crime_clustering_cut), round(0.75*nrow(chicago_crime_clustering_cut)))
#train <- Crime_chicago_def_clust_cut[index,] 
#test <- Crime_chicago_def_clust_cut[-index,]
train_label <- train_set[,1]
test_label <- test[,1]

#Optimum number of clusters. Elbow method
# Alternative using fviz function for Elbow method
library(factoextra)
library(NbClust)
set.seed(123)
train_small <- train_set[1:1000,]
test_small <- test[1:100,]

## Dendograms
library(tidyverse)      #data manipulation and visualization
library(class)          # to call class package for kNN
library(caret)
library(cluster)
# Divisive Hierarchical Clustering - diana
# compute divisive hierarchical clustering
div <- diana(train_small)
plot(div, main = "Divisive")


distance <- dist(train_small,method = "euclidean")
agg <- hclust(distance, method = "complete")
plot(agg,
     main = "Agglomerative, complete linkages")


library(fpc)
cstats.table <- function(dist, tree, k) {
clust.assess <- c("cluster.number","n","within.cluster.ss","average.within","average.between",
                  "wb.ratio","dunn2","avg.silwidth")
clust.size <- c("cluster.size")
stats.names <- c()
row.clust <- c()
output.stats <- matrix(ncol = k, nrow = length(clust.assess))
cluster.sizes <- matrix(ncol = k, nrow = k)
for(i in c(1:k)){
  row.clust[i] <- paste("Cluster-", i, " size")
}
for(i in c(2:k)){
  stats.names[i] <- paste("Test", i-1)
  
  for(j in seq_along(clust.assess)){
    output.stats[j, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.assess])[j]
    
  }
  
  for(d in 1:k) {
    cluster.sizes[d, i] <- unlist(cluster.stats(d = dist, clustering = cutree(tree, k = i))[clust.size])[d]
    dim(cluster.sizes[d, i]) <- c(length(cluster.sizes[i]), 1)
    cluster.sizes[d, i]
    
  }
}
output.stats.df <- data.frame(output.stats)
cluster.sizes <- data.frame(cluster.sizes)
cluster.sizes[is.na(cluster.sizes)] <- 0
rows.all <- c(clust.assess, row.clust)
# rownames(output.stats.df) <- clust.assess
output <- rbind(output.stats.df, cluster.sizes)[ ,-1]
colnames(output) <- stats.names[2:k]
rownames(output) <- rows.all
is.num <- sapply(output, is.numeric)
output[is.num] <- lapply(output[is.num], round, 2)
output
}
# I am capping the maximum amout of clusters by 7
# I want to choose a reasonable number, based on which I will be able to see basic differences between customer groups as a result
stats.df.divisive <- cstats.table(distance, div, 7)
stats.df.divisive

stats.df.aggl <-cstats.table(distance, agg, 7) #complete linkages looks like the most balanced approach
stats.df.aggl

#confusionMatrix(train_small, )
library("ggplot2")
library("reshape2")

Attaching package: ‘reshape2’

The following object is masked from ‘package:tidyr’:

    smiths

The following objects are masked from ‘package:data.table’:

    dcast, melt
library("purrr")
library("dplyr")
# let's start with a dendrogram
library("dendextend")

---------------------
Welcome to dendextend version 1.13.4
Type citation('dendextend') for how to cite the package.

Type browseVignettes(package = 'dendextend') for the package vignette.
The github page is: https://github.com/talgalili/dendextend/

Suggestions and bug-reports can be submitted at: https://github.com/talgalili/dendextend/issues
Or contact: <tal.galili@gmail.com>

    To suppress this message use:  suppressPackageStartupMessages(library(dendextend))
---------------------


Attaching package: ‘dendextend’

The following object is masked from ‘package:data.table’:

    set

The following object is masked from ‘package:stats’:

    cutree
dendro <- as.dendrogram(agg)
dendro.col <- dendro %>%
  set("branches_k_color", k = 8, value =   c("darkslategray", "darkslategray4", "darkslategray3", "gold3", "darkcyan", "cyan3", "gold3")) %>%
  set("branches_lwd", 0.6) %>%
  set("labels_colors", 
      value = c("darkslategray")) %>% 
  set("labels_cex", 0.5)
Length of color vector was shorter than the number of clusters - color vector was recycled
ggd1 <- as.ggdend(dendro.col)
ggplot(ggd1, theme = theme_minimal()) +
  labs(x = "Num. observations", y = "Height", title = "Dendrogram, k = 8")

NA
NA
NA

Arboles de Decision

## c50

library(dplyr)
library(MASS)        # for obtaining data
library(tidyverse)  # for data processing
library(rpart)      # for CART decision tree
library(rpart.plot) # for plotting CART
library(caret)      # for confusion matrix and more
library(rsample)    # for data splitting
library(data.table)
library(C50)


#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)

chicago_crime_trees <- subset(chicago_crime_subset, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))
chicago_crime_trees_tr <- subset(chicago_crime_subset_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude))

library(dplyr)
chicago_crime_trees %>% mutate_if(is.factor, as.character) -> chicago_crime_trees
chicago_crime_trees_tr %>% mutate_if(is.factor, as.character) -> chicago_crime_trees_tr

chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "ROBBERY"] <- "ROB"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "NARCOTICS"] <- "NAR"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "ASSAULT"] <- "ASS"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "WEAPONS VIOLATION"] <- "WV"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "CRIMINAL DAMAGE"] <- "CD"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "VIOLENT CRIME"] <- "VC"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "DECEPTIVE PRACTICE"] <- "DP"
chicago_crime_trees$primary_type[chicago_crime_trees$primary_type == "THEFT"] <- "TH"

chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "ROBBERY"] <- "ROB"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "NARCOTICS"] <- "NAR"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "ASSAULT"] <- "ASS"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "WEAPONS VIOLATION"] <- "WV"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "CRIMINAL DAMAGE"] <- "CD"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "VIOLENT CRIME"] <- "VC"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "DECEPTIVE PRACTICE"] <- "DP"
chicago_crime_trees_tr$primary_type[chicago_crime_trees_tr$primary_type == "THEFT"] <- "TH"

#train_c50<- chicago_crime_trees_tr
#test_c50<- chicago_crime_trees

crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)

#train_c50$location_description <- as.factor(train_c50$location_description)
#test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$primary_type <- as.factor(train_c50$primary_type)
test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(primary_type  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.2))  #Higher CF less prunning
summary(tree_result)

Call:
C5.0.formula(formula = primary_type ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.2))


C5.0 [Release 2.07 GPL Edition]     Fri May  8 13:49:43 2020
-------------------------------

Class specified by attribute `outcome'

Read 488358 cases (3 attributes) from undefined.data

Decision tree:

arrest = False: THEFT (396262/242319)
arrest = True:
:...district in {1,2,12,14,16,17,18,19,20,24,31}: THEFT (29329/19863)
    district in {3,4,5,6,7,8,9,10,11,15,22,25}: NARCOTICS (62767/36815)


Evaluation on training data (488358 cases):

        Decision Tree   
      ----------------  
      Size      Errors  

         3 298997(61.2%)   <<


        (a)    (b)    (c)    (d)    (e)    (f)    (g)    (h)    <-classified as
      -----  -----  -----  -----  -----  -----  -----  -----
                            4197         30630                  (a): class ASSAULT
                            1976         60313                  (b): class CRIMINAL DAMAGE
                             970         41627                  (c): class DECEPTIVE PRACTICE
                           25952          4001                  (d): class NARCOTICS
                            7181         65181                  (e): class ROBBERY
                            7604        163409                  (f): class THEFT
                            7881         56651                  (g): class VIOLENT CRIME
                            7006          3779                  (h): class WEAPONS VIOLATION


    Attribute usage:

    100.00% arrest
     18.86% district


Time: 0.2 secs
#Plotting the tree
plot(tree_result,subtree=NULL)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$primary_type)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$primary_type),
      "correct classified cases from", length(predictions))
[1] "The classification error in test set is: 61.0087722890678 % 47604 correct classified cases from 122089"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$primary_type)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$primary_type),
      "correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 61.2249620155705 % 189361 correct classified cases from 488358"
#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.1))  #Higher CF less prunning
summary(tree_result)

Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.1))


C5.0 [Release 2.07 GPL Edition]     Fri May  8 13:47:32 2020
-------------------------------

Class specified by attribute `outcome'

Read 488358 cases (4 attributes) from undefined.data

Decision tree:

primary_type in {NARCOTICS,WEAPONS VIOLATION}:
:...primary_type = WEAPONS VIOLATION:
:   :...arrest = False:
:   :   :...location_description <= 18:
:   :   :   :...location_description <= 14: 7 (9/6)
:   :   :   :   location_description > 14: 25 (400/355)
:   :   :   location_description > 18:
:   :   :   :...location_description <= 19: 11 (210/167)
:   :   :       location_description > 19:
:   :   :       :...location_description > 128: 11 (1516/1354)
:   :   :           location_description <= 128:
:   :   :           :...location_description > 110: 7 (534/464)
:   :   :               location_description <= 110:
:   :   :               :...location_description <= 64: 5 (50/39)
:   :   :                   location_description > 64: 4 (150/131)
:   :   arrest = True:
:   :   :...location_description > 113:
:   :       :...location_description <= 135:
:   :       :   :...location_description <= 121: 7 (1064/902)
:   :       :   :   location_description > 121: 10 (1567/1339)
:   :       :   location_description > 135:
:   :       :   :...location_description <= 141: 7 (3228/2755)
:   :       :       location_description > 141:
:   :       :       :...location_description <= 144: 10 (72/51)
:   :       :           location_description > 144: 11 (404/314)
:   :       location_description <= 113:
:   :       :...location_description <= 34:
:   :           :...location_description <= 15:
:   :           :   :...location_description <= 4: 7 (25/16)
:   :           :   :   location_description > 4: 16 (13)
:   :           :   location_description > 15:
:   :           :   :...location_description <= 17: 7 (466/413)
:   :           :       location_description > 17:
:   :           :       :...location_description <= 19: 11 (343/293)
:   :           :           location_description > 19:
:   :           :           :...location_description <= 30: 15 (23/18)
:   :           :               location_description > 30: 16 (7/4)
:   :           location_description > 34:
:   :           :...location_description <= 44: 5 (76/53)
:   :               location_description > 44:
:   :               :...location_description > 105:
:   :                   :...location_description <= 107: 4 (90/79)
:   :                   :   location_description > 107: 6 (206/174)
:   :                   location_description <= 105:
:   :                   :...location_description <= 73:
:   :                       :...location_description <= 55: 3 (41/35)
:   :                       :   location_description > 55: 1 (42/31)
:   :                       location_description > 73:
:   :                       :...location_description <= 77: 6 (134/104)
:   :                           location_description > 77:
:   :                           :...location_description <= 101: 5 (45/39)
:   :                               location_description > 101:
:   :                               :...location_description <= 103: 11 (63/49)
:   :                                   location_description > 103: 1 (7/4)
:   primary_type = NARCOTICS:
:   :...location_description > 110:
:       :...location_description > 133: 11 (10740/8406)
:       :   location_description <= 133:
:       :   :...location_description > 131: 11 (8624/4943)
:       :       location_description <= 131:
:       :       :...location_description <= 113: 11 (827/288)
:       :           location_description > 113:
:       :           :...location_description <= 121:
:       :               :...location_description <= 116: 7 (1519/1223)
:       :               :   location_description > 116: 11 (996/597)
:       :               location_description > 121:
:       :               :...location_description <= 127:
:       :                   :...location_description <= 124: 11 (110/88)
:       :                   :   location_description > 124: 18 (52/45)
:       :                   location_description > 127:
:       :                   :...location_description > 129: 10 (82/69)
:       :                       location_description <= 129:
:       :                       :...location_description <= 128: 8 (17/14)
:       :                           location_description > 128: 25 (369/327)
:       location_description <= 110:
:       :...location_description <= 19:
:           :...location_description > 16: 11 (3029/2243)
:           :   location_description <= 16:
:           :   :...location_description <= 2: 11 (230/129)
:           :       location_description > 2: 16 (128/33)
:           location_description > 19:
:           :...location_description > 107: 11 (821/674)
:               location_description <= 107:
:               :...location_description > 77:
:                   :...location_description <= 79: 16 (217/44)
:                   :   location_description > 79:
:                   :   :...location_description > 101:
:                   :       :...location_description <= 103: 11 (347/240)
:                   :       :   location_description > 103:
:                   :       :   :...location_description <= 105: 1 (70/4)
:                   :       :       location_description > 105: 10 (298/226)
:                   :       location_description <= 101:
:                   :       :...location_description <= 87: 7 (201/165)
:                   :           location_description > 87:
:                   :           :...location_description <= 90: 18 (31/16)
:                   :               location_description > 90:
:                   :               :...location_description > 98: 15 (39/31)
:                   :                   location_description <= 98:
:                   :                   :...location_description <= 92: 10 (41/28)
:                   :                       location_description > 92: 12 (59/49)
:                   location_description <= 77:
:                   :...location_description > 73: 11 (428/308)
:                       location_description <= 73:
:                       :...location_description > 62: 25 (119/106)
:                           location_description <= 62:
:                           :...location_description > 54:
:                               :...location_description > 59: 1 (54/31)
:                               :   location_description <= 59:
:                               :   :...location_description <= 57: 1 (66/49)
:                               :       location_description > 57: 6 (83/50)
:                               location_description <= 54:
:                               :...location_description > 50: 11 (128/95)
:                                   location_description <= 50:
:                                   :...location_description > 44:
:                                       :...location_description <= 48: 18 (20/9)
:                                       :   location_description > 48: 1 (13/10)
:                                       location_description <= 44:
:                                       :...location_description <= 27: [S1]
:                                           location_description > 27: [S2]
primary_type in {ASSAULT,CRIMINAL DAMAGE,ROBBERY,VIOLENT CRIME}:
:...location_description <= 19:
:   :...location_description <= 16:
:   :   :...location_description <= 2: 7 (379/308)
:   :   :   location_description > 2: 16 (777/111)
:   :   location_description > 16:
:   :   :...location_description > 18: 3 (28087/24753)
:   :       location_description <= 18:
:   :       :...location_description > 17: 18 (39/34)
:   :           location_description <= 17:
:   :           :...primary_type in {CRIMINAL DAMAGE,
:   :               :                VIOLENT CRIME}: 11 (2839/2595)
:   :               primary_type = ASSAULT:
:   :               :...arrest = False: 25 (785/709)
:   :               :   arrest = True: 11 (179/162)
:   :               primary_type = ROBBERY:
:   :               :...arrest = False: 11 (1916/1722)
:   :                   arrest = True: 19 (159/142)
:   location_description > 19:
:   :...location_description <= 109:
:       :...location_description <= 40:
:       :   :...location_description > 34:
:       :   :   :...location_description > 38: 5 (868/648)
:       :   :   :   location_description <= 38:
:       :   :   :   :...location_description <= 36: 5 (742/599)
:       :   :   :       location_description > 36:
:       :   :   :       :...primary_type = CRIMINAL DAMAGE: 19 (7/5)
:       :   :   :           primary_type in {ROBBERY,
:       :   :   :           :                VIOLENT CRIME}: 1 (193/124)
:       :   :   :           primary_type = ASSAULT:
:       :   :   :           :...arrest = False: 2 (82/53)
:       :   :   :               arrest = True: 1 (22/15)
:       :   :   location_description <= 34:
:       :   :   :...location_description <= 25:
:       :   :       :...primary_type in {ASSAULT,CRIMINAL DAMAGE,ROBBERY}:
:       :   :       :   :...location_description <= 20: 9 (49/42)
:       :   :       :   :   location_description > 20: 1 (602/506)
:       :   :       :   primary_type = VIOLENT CRIME:
:       :   :       :   :...location_description <= 21:
:       :   :       :       :...location_description <= 20: 6 (20/16)
:       :   :       :       :   location_description > 20: 1 (46/35)
:       :   :       :       location_description > 21:
:       :   :       :       :...location_description <= 24: 8 (198/173)
:       :   :       :           location_description > 24: 1 (24/17)
:       :   :       location_description > 25:
:       :   :       :...location_description <= 26:
:       :   :           :...primary_type in {ASSAULT,CRIMINAL DAMAGE,
:       :   :           :   :                ROBBERY}: 19 (470/369)
:       :   :           :   primary_type = VIOLENT CRIME: 18 (1234/866)
:       :   :           location_description > 26:
:       :   :           :...location_description > 32: 17 (176/153)
:       :   :               location_description <= 32:
:       :   :               :...location_description <= 29: 6 (314/281)
:       :   :                   location_description > 29:
:       :   :                   :...location_description <= 30: 1 (30/12)
:       :   :                       location_description > 30: [S3]
:       :   location_description > 40:
:       :   :...location_description <= 79:
:       :       :...location_description > 73:
:       :       :   :...location_description > 77: 1 (538/424)
:       :       :   :   location_description <= 77:
:       :       :   :   :...primary_type = CRIMINAL DAMAGE: 6 (557/488)
:       :       :   :       primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
:       :       :   :       :...primary_type = ASSAULT: 6 (798/697)
:       :       :   :           primary_type = ROBBERY: 11 (1721/1425)
:       :       :   :           primary_type = VIOLENT CRIME:
:       :       :   :           :...location_description <= 75: 10 (7/4)
:       :       :   :               location_description > 75: 11 (850/747)
:       :       :   location_description <= 73:
:       :       :   :...primary_type = CRIMINAL DAMAGE:
:       :       :       :...location_description <= 54:
:       :       :       :   :...location_description <= 44:
:       :       :       :   :   :...arrest = False: 2 (286/255)
:       :       :       :   :   :   arrest = True: 7 (9/6)
:       :       :       :   :   location_description > 44:
:       :       :       :   :   :...location_description <= 50:
:       :       :       :   :       :...location_description <= 46: 4 (45/39)
:       :       :       :   :       :   location_description > 46:
:       :       :       :   :       :   :...location_description <= 47: 1 (21/15)
:       :       :       :   :       :       location_description > 47: 12 (627/559)
:       :       :       :   :       location_description > 50:
:       :       :       :   :       :...location_description <= 52:
:       :       :       :   :           :...location_description <= 51: 1 (225/203)
:       :       :       :   :           :   location_description > 51: 6 (7/4)
:       :       :       :   :           location_description > 52:
:       :       :       :   :           :...arrest = True: 9 (32/27)
:       :       :       :   :               arrest = False: [S4]
:       :       :       :   location_description > 54:
:       :       :       :   :...location_description <= 60:
:       :       :       :       :...arrest = False: 24 (810/591)
:       :       :       :       :   arrest = True: 1 (74/53)
:       :       :       :       location_description > 60:
:       :       :       :       :...arrest = True: 3 (44/38)
:       :       :       :           arrest = False:
:       :       :       :           :...location_description > 64: 8 (540/468)
:       :       :       :               location_description <= 64:
:       :       :       :               :...location_description > 62: 18 (110/89)
:       :       :       :                   location_description <= 62: [S5]
:       :       :       primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
:       :       :       :...location_description <= 54:
:       :       :           :...location_description > 50:
:       :       :           :   :...location_description > 52:
:       :       :           :   :   :...location_description <= 53: 6 (1016/913)
:       :       :           :   :   :   location_description > 53: 11 (653/584)
:       :       :           :   :   location_description <= 52: [S6]
:       :       :           :   location_description <= 50:
:       :       :           :   :...location_description > 46:
:       :       :           :       :...location_description <= 48: 1 (140/98)
:       :       :           :       :   location_description > 48:
:       :       :           :       :   :...location_description <= 49: 1 (1110/952)
:       :       :           :       :       location_description > 49: 12 (336/275)
:       :       :           :       location_description <= 46:
:       :       :           :       :...arrest = True:
:       :       :           :           :...location_description <= 44: 18 (87/77)
:       :       :           :           :   location_description > 44: 5 (39/31)
:       :       :           :           arrest = False:
:       :       :           :           :...location_description > 43: 8 (91/78)
:       :       :           :               location_description <= 43: [S7]
:       :       :           location_description > 54:
:       :       :           :...location_description <= 60:
:       :       :               :...primary_type in {ASSAULT,
:       :       :               :   :                VIOLENT CRIME}: 1 (1631/1245)
:       :       :               :   primary_type = ROBBERY:
:       :       :               :   :...arrest = False: 1 (700/554)
:       :       :               :       arrest = True:
:       :       :               :       :...location_description <= 57: 1 (122/98)
:       :       :               :           location_description > 57: [S8]
:       :       :               location_description > 60:
:       :       :               :...location_description <= 64:
:       :       :                   :...location_description <= 62: 3 (230/207)
:       :       :                   :   location_description > 62: 1 (956/765)
:       :       :                   location_description > 64:
:       :       :                   :...location_description > 67:
:       :       :                       :...location_description <= 68: [S9]
:       :       :                       :   location_description > 68: [S10]
:       :       :                       location_description <= 67:
:       :       :                       :...location_description > 65: [S11]
:       :       :                           location_description <= 65:
:       :       :                           :...arrest = False: 16 (196/171)
:       :       :                               arrest = True: [S12]
:       :       location_description > 79:
:       :       :...location_description <= 89:
:       :           :...location_description > 86:
:       :           :   :...arrest = False: 18 (613/430)
:       :           :   :   arrest = True: 1 (348/212)
:       :           :   location_description <= 86:
:       :           :   :...location_description > 84:
:       :           :       :...arrest = False: 12 (782/657)
:       :           :       :   arrest = True: 18 (384/294)
:       :           :       location_description <= 84:
:       :           :       :...location_description > 81: 3 (55/49)
:       :           :           location_description <= 81:
:       :           :           :...primary_type = ASSAULT: 18 (425/389)
:       :           :               primary_type = CRIMINAL DAMAGE: 6 (225/205)
:       :           :               primary_type in {ROBBERY,
:       :           :                                VIOLENT CRIME}: 19 (1236/1138)
:       :           location_description > 89:
:       :           :...location_description > 100:
:       :               :...arrest = True:
:       :               :   :...location_description <= 106: 1 (1848/1539)
:       :               :   :   location_description > 106: 6 (1264/1133)
:       :               :   arrest = False:
:       :               :   :...primary_type = CRIMINAL DAMAGE:
:       :               :       :...location_description > 107: 1 (3235/2863)
:       :               :       :   location_description <= 107:
:       :               :       :   :...location_description <= 105: 8 (1909/1754)
:       :               :       :       location_description > 105: 19 (257/231)
:       :               :       primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
:       :               :       :...location_description <= 104:
:       :               :           :...location_description > 103: 1 (54/35)
:       :               :           :   location_description <= 103: [S13]
:       :               :           location_description > 104:
:       :               :           :...location_description > 108: 8 (2901/2669)
:       :               :               location_description <= 108:
:       :               :               :...location_description <= 105: 1 (63/52)
:       :               :                   location_description > 105: [S14]
:       :               location_description <= 100:
:       :               :...location_description > 98:
:       :                   :...primary_type = CRIMINAL DAMAGE: 2 (40/34)
:       :                   :   primary_type = ROBBERY: 20 (63/56)
:       :                   :   primary_type = VIOLENT CRIME: 15 (719/607)
:       :                   :   primary_type = ASSAULT:
:       :                   :   :...arrest = False: 2 (185/161)
:       :                   :       arrest = True: 15 (16/12)
:       :                   location_description <= 98:
:       :                   :...location_description > 96: 18 (121/99)
:       :                       location_description <= 96:
:       :                       :...location_description <= 92:
:       :                           :...location_description <= 90: 5 (54/40)
:       :                           :   location_description > 90: 12 (94/73)
:       :                           location_description > 92:
:       :                           :...arrest = True:
:       :                               :...location_description <= 94: 1 (145/71)
:       :                               :   location_description > 94: 14 (24/20)
:       :                               arrest = False:
:       :                               :...location_description <= 93: 19 (37/27)
:       :                                   location_description > 93: [S15]
:       location_description > 109:
:       :...location_description <= 121:
:           :...location_description > 119: 8 (13730/11829)
:           :   location_description <= 119:
:           :   :...location_description > 116:
:           :       :...primary_type in {ASSAULT,VIOLENT CRIME}:
:           :       :   :...arrest = False: 11 (2154/1959)
:           :       :   :   arrest = True: 7 (449/403)
:           :       :   primary_type in {CRIMINAL DAMAGE,ROBBERY}:
:           :       :   :...arrest = False:
:           :       :       :...primary_type = CRIMINAL DAMAGE: 19 (667/614)
:           :       :       :   primary_type = ROBBERY: 2 (616/568)
:           :       :       arrest = True:
:           :       :       :...primary_type = CRIMINAL DAMAGE: 19 (59/50)
:           :       :           primary_type = ROBBERY: 24 (413/370)
:           :       location_description <= 116:
:           :       :...location_description <= 111:
:           :           :...location_description <= 110: 9 (45/37)
:           :           :   location_description > 110:
:           :           :   :...primary_type = ASSAULT: 19 (84/75)
:           :           :       primary_type = VIOLENT CRIME: 11 (158/140)
:           :           :       primary_type = ROBBERY: 3 (181/140)
:           :           :       primary_type = CRIMINAL DAMAGE:
:           :           :       :...arrest = False: 11 (67/57)
:           :           :           arrest = True: 10 (61/51)
:           :           location_description > 111:
:           :           :...primary_type = ROBBERY:
:           :               :...arrest = False: 8 (11026/9771)
:           :               :   arrest = True: 5 (963/871)
:           :               primary_type in {ASSAULT,CRIMINAL DAMAGE,
:           :               :                VIOLENT CRIME}:
:           :               :...primary_type in {ASSAULT,
:           :                   :                VIOLENT CRIME}: 7 (9802/8729)
:           :                   primary_type = CRIMINAL DAMAGE:
:           :                   :...arrest = False: 8 (10185/9121)
:           :                       arrest = True: 4 (418/370)
:           location_description > 121:
:           :...location_description <= 122:
:               :...primary_type in {ASSAULT,CRIMINAL DAMAGE,
:               :   :                ROBBERY}: 1 (4301/3863)
:               :   primary_type = VIOLENT CRIME: 18 (1480/1277)
:               location_description > 122:
:               :...location_description <= 130:
:                   :...location_description > 128: 8 (7069/6410)
:                   :   location_description <= 128:
:                   :   :...location_description <= 126: 25 (20/16)
:                   :       location_description > 126:
:                   :       :...primary_type in {ASSAULT,
:                   :           :                VIOLENT CRIME}: 11 (750/668)
:                   :           primary_type = ROBBERY:
:                   :           :...arrest = False: 12 (78/68)
:                   :           :   arrest = True: 24 (90/73)
:                   :           primary_type = CRIMINAL DAMAGE:
:                   :           :...arrest = True: 9 (13/10)
:                   :               arrest = False:
:                   :               :...location_description <= 127: 8 (87/77)
:                   :                   location_description > 127: 15 (44/38)
:                   location_description > 130:
:                   :...primary_type = CRIMINAL DAMAGE:
:                       :...location_description > 134: 8 (24708/22873)
:                       :   location_description <= 134:
:                       :   :...location_description <= 133:
:                       :       :...arrest = False: 19 (368/337)
:                       :       :   arrest = True: 10 (168/150)
:                       :       location_description > 133:
:                       :       :...arrest = False: 18 (648/598)
:                       :           arrest = True: 8 (60/50)
:                       primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}:
:                       :...location_description <= 136:
:                           :...location_description <= 133:
:                           :   :...arrest = False: 11 (21858/19830)
:                           :   :   arrest = True: [S16]
:                           :   location_description > 133:
:                           :   :...location_description > 134: 19 (202/132)
:                           :       location_description <= 134: [S17]
:                           location_description > 136:
:                           :...location_description > 151:
:                               :...location_description > 152: 7 (45/37)
:                               :   location_description <= 152: [S18]
:                               location_description <= 151:
:                               :...primary_type = ASSAULT:
:                                   :...location_description > 146:
:                                   :   :...arrest = False: 10 (138/125)
:                                   :   :   arrest = True: 15 (27/22)
:                                   :   location_description <= 146:
:                                   :   :...location_description <= 139: [S19]
:                                   :       location_description > 139: [S20]
:                                   primary_type in {ROBBERY,VIOLENT CRIME}:
:                                   :...location_description <= 140:
:                                       :...location_description <= 137: 11 (21072/19062)
:                                       :   location_description > 137: [S21]
:                                       location_description > 140:
:                                       :...location_description <= 144: [S22]
:                                           location_description > 144: [S23]
primary_type in {DECEPTIVE PRACTICE,THEFT}:
:...location_description > 136:
    :...location_description > 150:
    :   :...arrest = False: 9 (251/215)
    :   :   arrest = True: 1 (36/28)
    :   location_description <= 150:
    :   :...primary_type = DECEPTIVE PRACTICE:
    :       :...arrest = False:
    :       :   :...location_description <= 138: 1 (1926/1643)
    :       :   :   location_description > 138: 18 (668/565)
    :       :   arrest = True:
    :       :   :...location_description <= 138: 7 (338/306)
    :       :       location_description > 138:
    :       :       :...location_description > 141: 3 (30/24)
    :       :           location_description <= 141:
    :       :           :...location_description <= 139: 18 (6/3)
    :       :               location_description > 139: 19 (44/35)
    :       primary_type = THEFT:
    :       :...arrest = True:
    :           :...location_description <= 138: 8 (1922/1757)
    :           :   location_description > 138:
    :           :   :...location_description > 144: 22 (118/101)
    :           :       location_description <= 144:
    :           :       :...location_description <= 139: 4 (66/54)
    :           :           location_description > 139:
    :           :           :...location_description <= 141: 19 (18/11)
    :           :               location_description > 141: 11 (8/5)
    :           arrest = False:
    :           :...location_description <= 138: 12 (53034/48284)
    :               location_description > 138:
    :               :...location_description <= 141: 18 (552/404)
    :                   location_description > 141:
    :                   :...location_description <= 143: 7 (365/302)
    :                       location_description > 143:
    :                       :...location_description <= 146: 1 (174/142)
    :                           location_description > 146:
    :                           :...location_description <= 147: 14 (4302/3949)
    :                               location_description > 147: 1 (291/254)
    location_description <= 136:
    :...location_description > 121:
        :...location_description <= 124:
        :   :...arrest = False: 1 (8654/5129)
        :   :   arrest = True: 18 (304/235)
        :   location_description > 124:
        :   :...location_description <= 131:
        :       :...location_description > 128: 8 (1795/1585)
        :       :   location_description <= 128:
        :       :   :...arrest = True: 24 (22/16)
        :       :       arrest = False:
        :       :       :...location_description <= 127: 1 (319/268)
        :       :           location_description > 127: 12 (88/74)
        :       location_description > 131:
        :       :...location_description <= 133:
        :           :...arrest = False: 1 (5383/4398)
        :           :   arrest = True:
        :           :   :...primary_type = DECEPTIVE PRACTICE: 10 (168/136)
        :           :       primary_type = THEFT: 18 (389/334)
        :           location_description > 133:
        :           :...location_description > 134: 19 (333/268)
        :               location_description <= 134:
        :               :...primary_type = DECEPTIVE PRACTICE: 18 (1467/1116)
        :                   primary_type = THEFT: 1 (9510/7853)
        location_description <= 121:
        :...location_description > 109:
            :...location_description > 117:
            :   :...location_description <= 120: 19 (5973/5206)
            :   :   location_description > 120:
            :   :   :...primary_type = THEFT: 8 (4387/4014)
            :   :       primary_type = DECEPTIVE PRACTICE:
            :   :       :...arrest = False: 16 (42/37)
            :   :           arrest = True: 19 (10/6)
            :   location_description <= 117:
            :   :...location_description > 111:
            :       :...primary_type = DECEPTIVE PRACTICE: 8 (13541/12344)
            :       :   primary_type = THEFT: 5 (10708/9898)
            :       location_description <= 111:
            :       :...location_description <= 110: 10 (65/54)
            :           location_description > 110:
            :           :...primary_type = THEFT: 11 (86/70)
            :               primary_type = DECEPTIVE PRACTICE:
            :               :...arrest = False: 9 (59/45)
            :                   arrest = True: 5 (20/15)
            location_description <= 109:
            :...location_description <= 19:
                :...location_description > 16:
                :   :...location_description <= 17: 11 (1754/1609)
                :   :   location_description > 17: 19 (11235/10092)
                :   location_description <= 16:
                :   :...location_description > 2: 16 (1665/302)
                :       location_description <= 2:
                :       :...location_description <= 1: 19 (1757/1494)
                :           location_description > 1: 7 (79/61)
                location_description > 19:
                :...location_description <= 64:
                    :...location_description > 62:
                    :   :...primary_type = DECEPTIVE PRACTICE: 18 (1288/771)
                    :   :   primary_type = THEFT: 1 (8184/5962)
                    :   location_description <= 62:
                    :   :...location_description <= 31:
                    :       :...location_description > 25: 18 (2786/1577)
                    :       :   location_description <= 25:
                    :       :   :...arrest = True:
                    :       :       :...location_description > 23: 2 (70/55)
                    :       :       :   location_description <= 23:
                    :       :       :   :...location_description <= 20: 17 (41/26)
                    :       :       :       location_description > 20: 18 (14/7)
                    :       :       arrest = False:
                    :       :       :...location_description <= 21:
                    :       :           :...location_description <= 20: 6 (77/66)
                    :       :           :   location_description > 20: 1 (1059/830)
                    :       :           location_description > 21:
                    :       :           :...location_description <= 23: 19 (1204/985)
                    :       :               location_description > 23: [S24]
                    :       location_description > 31:
                    :       :...location_description > 55:
                    :           :...location_description > 60: 6 (762/664)
                    :           :   location_description <= 60:
                    :           :   :...arrest = False: 1 (3966/2360)
                    :           :       arrest = True: [S25]
                    :           location_description <= 55:
                    :           :...location_description <= 50:
                    :               :...location_description > 46:
                    :               :   :...location_description <= 48: 1 (213/137)
                    :               :   :   location_description > 48: [S26]
                    :               :   location_description <= 46:
                    :               :   :...location_description > 34: [S27]
                    :               :       location_description <= 34: [S28]
                    :               location_description > 50:
                    :               :...location_description > 54: [S29]
                    :                   location_description <= 54:
                    :                   :...arrest = True: 6 (663/591)
                    :                       arrest = False: [S30]
                    location_description > 64:
                    :...location_description <= 77:
                        :...location_description > 74: 6 (3417/3032)
                        :   location_description <= 74:
                        :   :...location_description <= 65: 8 (979/817)
                        :       location_description > 65:
                        :       :...location_description <= 67: 1 (1995/1769)
                        :           location_description > 67:
                        :           :...location_description <= 69: 9 (87/72)
                        :               location_description > 69:
                        :               :...location_description <= 70: 1 (27/17)
                        :                   location_description > 70: 16 (54/43)
                        location_description > 77:
                        :...location_description <= 87:
                            :...location_description > 82: 18 (884/655)
                            :   location_description <= 82:
                            :   :...location_description <= 79: 1 (261/170)
                            :       location_description > 79:
                            :       :...primary_type = THEFT: 19 (5376/4774)
                            :           primary_type = DECEPTIVE PRACTICE:
                            :           :...arrest = False: 18 (438/392)
                            :               arrest = True: 31 (24/17)
                            location_description > 87:
                            :...location_description <= 90: 18 (1670/972)
                                location_description > 90:
                                :...location_description > 107:
                                    :...arrest = False: 1 (8715/7563)
                                    :   arrest = True: 8 (331/298)
                                    location_description <= 107:
                                    :...location_description > 102: 1 (1978/1288)
                                        location_description <= 102:
                                        :...location_description <= 93: [S31]
                                            location_description > 93: [S32]

SubTree [S1]

location_description <= 25: 1 (12/8)
location_description > 25: 9 (12/9)

SubTree [S2]

location_description > 36: 11 (124/87)
location_description <= 36:
:...location_description <= 34: 11 (15/11)
    location_description > 34: 5 (32/23)

SubTree [S3]

primary_type in {ASSAULT,ROBBERY,VIOLENT CRIME}: 18 (45/32)
primary_type = CRIMINAL DAMAGE: 19 (12/9)

SubTree [S4]

location_description <= 53: 7 (173/152)
location_description > 53: 1 (42/38)

SubTree [S5]

location_description <= 61: 6 (33/26)
location_description > 61: 8 (64/56)

SubTree [S6]

primary_type in {ASSAULT,VIOLENT CRIME}: 11 (784/701)
primary_type = ROBBERY:
:...arrest = False: 25 (492/451)
    arrest = True: 7 (321/284)

SubTree [S7]

location_description <= 42: 15 (4/2)
location_description > 42:
:...primary_type = ASSAULT: 2 (84/71)
    primary_type in {ROBBERY,VIOLENT CRIME}: 7 (303/272)

SubTree [S8]

location_description <= 58: 6 (297/213)
location_description > 58: 1 (87/69)

SubTree [S9]

primary_type in {ASSAULT,VIOLENT CRIME}: 9 (81/67)
primary_type = ROBBERY: 11 (54/39)

SubTree [S10]

location_description <= 70: 1 (43/30)
location_description > 70: 6 (29/24)

SubTree [S11]

primary_type in {ASSAULT,ROBBERY}: 1 (491/429)
primary_type = VIOLENT CRIME: 19 (119/100)

SubTree [S12]

primary_type in {ASSAULT,VIOLENT CRIME}: 8 (15/11)
primary_type = ROBBERY: 3 (15/12)

SubTree [S13]

primary_type in {ASSAULT,VIOLENT CRIME}: 1 (2984/2692)
primary_type = ROBBERY: 8 (1692/1525)

SubTree [S14]

location_description > 106: 11 (20/17)
location_description <= 106:
:...primary_type in {ASSAULT,VIOLENT CRIME}: 4 (1015/934)
    primary_type = ROBBERY: 1 (419/376)

SubTree [S15]

primary_type = ROBBERY:
:...location_description <= 95: 1 (24/20)
:   location_description > 95: 17 (44/35)
primary_type in {ASSAULT,CRIMINAL DAMAGE,VIOLENT CRIME}:
:...primary_type = VIOLENT CRIME: 1 (101/87)
    primary_type = ASSAULT:
    :...location_description <= 95: 12 (70/57)
    :   location_description > 95: 25 (67/60)
    primary_type = CRIMINAL DAMAGE:
    :...location_description <= 95: 16 (34/29)
        location_description > 95: 19 (86/75)

SubTree [S16]

primary_type = ASSAULT: 11 (1106/1018)
primary_type = ROBBERY: 10 (754/695)
primary_type = VIOLENT CRIME: 19 (2046/1857)

SubTree [S17]

primary_type in {ASSAULT,VIOLENT CRIME}: 1 (1582/1388)
primary_type = ROBBERY:
:...arrest = False: 25 (1418/1283)
    arrest = True: 1 (559/494)

SubTree [S18]

primary_type in {ASSAULT,VIOLENT CRIME}: 9 (100/79)
primary_type = ROBBERY: 12 (182/150)

SubTree [S19]

location_description > 138: 4 (91/77)
location_description <= 138:
:...arrest = False: 9 (5918/5476)
    arrest = True: 4 (1141/1042)

SubTree [S20]

location_description > 143: 2 (29/23)
location_description <= 143:
:...location_description <= 141: 18 (15/11)
    location_description > 141: 11 (33/27)

SubTree [S21]

location_description > 139: 18 (127/103)
location_description <= 139:
:...location_description <= 138: 4 (3/2)
    location_description > 138:
    :...primary_type = VIOLENT CRIME: 18 (210/172)
        primary_type = ROBBERY:
        :...arrest = False: 17 (105/93)
            arrest = True: 4 (69/60)

SubTree [S22]

primary_type = ROBBERY:
:...arrest = False: 7 (476/398)
:   arrest = True: 11 (45/38)
primary_type = VIOLENT CRIME:
:...arrest = False: 11 (99/76)
    arrest = True: 7 (15/9)

SubTree [S23]

location_description <= 146: 18 (127/107)
location_description > 146:
:...location_description > 147: 18 (84/76)
    location_description <= 147:
    :...primary_type = ROBBERY: 8 (508/472)
        primary_type = VIOLENT CRIME:
        :...arrest = False: 25 (683/622)
            arrest = True: 9 (95/86)

SubTree [S24]

location_description <= 24: 8 (91/77)
location_description > 24: 1 (1814/1549)

SubTree [S25]

primary_type = DECEPTIVE PRACTICE: 11 (301/183)
primary_type = THEFT: 1 (85/62)

SubTree [S26]

location_description <= 49: 1 (1772/1335)
location_description > 49: 12 (454/372)

SubTree [S27]

location_description <= 41: 5 (295/240)
location_description > 41: 2 (542/497)

SubTree [S28]

location_description <= 32: 1 (9/5)
location_description > 32:
:...location_description <= 33: 6 (134/109)
    location_description > 33: 17 (11/7)

SubTree [S29]

primary_type = DECEPTIVE PRACTICE: 1 (32/10)
primary_type = THEFT: 8 (193/143)

SubTree [S30]

location_description <= 52: 1 (1654/1431)
location_description > 52:
:...location_description > 53: 7 (366/326)
    location_description <= 53:
    :...primary_type = DECEPTIVE PRACTICE: 1 (44/38)
        primary_type = THEFT: 6 (730/661)

SubTree [S31]

location_description <= 92: 10 (12/3)
location_description > 92: 18 (114/71)

SubTree [S32]

location_description > 101: 1 (13339/11253)
location_description <= 101:
:...location_description > 99: 19 (498/430)
    location_description <= 99:
    :...location_description > 96: 18 (157/102)
        location_description <= 96:
        :...location_description <= 95: 1 (206/128)
            location_description > 95: 12 (232/205)


Evaluation on training data (488358 cases):

        Decision Tree   
      ----------------  
      Size      Errors  

       348 417035(85.4%)   <<


      Class   Cases   False   False
                        Pos     Neg
      -----   -----   -----   -----
      1       32320   75133   12783
      2       20764    1717   20547
      3       20127   25258   16702
      4       23909    2788   23609
      5       18737   12496   17341
      6       27195    9451   25880
      7       22712   17537   20083
      8       30292   88386   20639
      9       21249    6165   20672
      10      21641    2931   21139
      11      32073   73020   17631
      12      26996   50823   21783
      14      20450    3969   20093
      15      17498     730   17356
      16      16846     774   14487
      17      14975     314   14912
      18      32110   11928   27449
      19      25431   28462   21636
      20       9202      56    9195
      22      14605     101   14588
      24      14664    1050   14379
      25      24550    3929   24126
      31         12      17       5


    Attribute usage:

    100.00% primary_type
    100.00% location_description
     42.20% arrest


Time: 0.5 secs
#Plotting the tree
plot(tree_result,faclen=10, clip.facs=TRUE,subtree=NULL, tweak=1, digits=2)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))
[1] "The classification error in test set is: 90.6715592723341 % 11389 correct classified cases from 122089"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 85.3953452180572 % 71323 correct classified cases from 488358"
#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(arrest  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.9))  #Higher CF less prunning
summary(tree_result)
#Plotting the tree
plot(tree_result,faclen=10, clip.facs=TRUE,subtree=NULL, tweak=1, digits=2)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$arrest)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$arrest),
      "correct classified cases from", length(predictions))

pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$arrest)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$arrest),
      "correct classified cases from", length(pred_train))
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#assault <- subset(assault, select=-c(location_description))
#assault_tr <- subset(assault_tr, select=-c(location_description))

assault_tr <- subset(assault_tr, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18" | district == "9" | district=="10" | district == "22" | district == "15" )
assault <- subset(assault, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18" | district == "9" | district=="10" | district == "22" | district == "15" )

#train_c50<- subset(assault_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#test_c50<- subset(assault, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

crime_split_c50<- initial_split(subset(assault_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)

train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.0001))  #Higher CF less prunning
summary(tree_result)

Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 1e-04))


C5.0 [Release 2.07 GPL Edition]     Fri May  8 13:51:43 2020
-------------------------------

Class specified by attribute `outcome'

Read 21338 cases (4 attributes) from undefined.data

Decision tree:

location_description <= 13:
:...location_description <= 12: 8 (529/437)
:   location_description > 12: 3 (2139/1703)
location_description > 13:
:...location_description <= 67:
    :...location_description <= 28:
    :   :...location_description <= 25: 18 (182/150)
    :   :   location_description > 25: 5 (267/200)
    :   location_description > 28:
    :   :...location_description > 55:
    :       :...location_description <= 56: 10 (127/102)
    :       :   location_description > 56: 1 (1376/1111)
    :       location_description <= 55:
    :       :...location_description <= 51: 1 (1383/1125)
    :           location_description > 51:
    :           :...location_description <= 52: 6 (561/464)
    :               location_description > 52:
    :               :...location_description <= 53: 1 (130/72)
    :                   location_description > 53: 6 (264/229)
    location_description > 67:
    :...location_description <= 75:
        :...location_description <= 71: 4 (622/542)
        :   location_description > 71: 5 (3744/3222)
        location_description > 75:
        :...location_description <= 76: 1 (644/505)
            location_description > 76:
            :...location_description <= 81: 4 (1480/1288)
                location_description > 81:
                :...location_description > 83: 9 (4532/3983)
                    location_description <= 83:
                    :...location_description <= 82: 4 (2819/2481)
                        location_description > 82: 1 (539/441)


Evaluation on training data (21338 cases):

        Decision Tree   
      ----------------  
      Size      Errors  

        17 18055(84.6%)   <<


       (a)   (b)   (c)   (d)   (e)   (f)   (g)   (h)   (i)   (j)   (k)   (l)    <-classified as
      ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----
       818    43   245    87    33          10   262     5          24          (a): class 1
       245   436   444   287    86          36   360     1          12          (b): class 3
       339   252   610   525    69          56   482    22          12          (c): class 4
       203   107   432   589    55          27   333     8          10          (d): class 5
       441   334   514   419   132          42   417                20          (e): class 6
       297   210   468   526   128          56   465    18           9          (f): class 7
       396   141   525   382    53          92   492    17          20          (g): class 8
       303   129   402   307    81          74   549                19          (h): class 9
       221   173   461   267    47          60   432    25           9          (i): class 10
       199   213   324   236    46          33   289    17           6          (j): class 15
       439    72   221   142    47          18   206    14          32          (k): class 18
       171    29   275   244    48          25   245                 9          (l): class 22


    Attribute usage:

    100.00% location_description


Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))
[1] "The classification error in test set is: 91.1886014248219 % 470 correct classified cases from 5334"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 84.6143031211922 % 3283 correct classified cases from 21338"
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#criminal_damage <- subset(criminal_damage, select=-c(location_description))
#criminal_damage_tr <- subset( criminal_damage_tr, select=-c(location_description))
criminal_damage_tr <- subset(criminal_damage_tr, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18"  | district == "9" | district=="20" | district == "25" | district == "11")
criminal_damage <- subset(criminal_damage, district=="3" | district == "4" | district == "5" | district=="6" | district == "7" | district=="8" | district == "1" | district == "18"  | district == "9" | district=="20" | district == "25" | district == "11")

train_c50<- subset(criminal_damage_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(criminal_damage, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)

train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)

#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.001))  #Higher CF less prunning
summary(tree_result)

Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.001))


C5.0 [Release 2.07 GPL Edition]     Wed May  6 16:43:00 2020
-------------------------------

Class specified by attribute `outcome'

Read 45588 cases (4 attributes) from undefined.data

Decision tree:

location_description in {ABANDONED BUILDING,
:                        AIRPORT BUILDING NON-TERMINAL - NON-SECURE AREA,
:                        AIRPORT BUILDING NON-TERMINAL - SECURE AREA,
:                        AIRPORT EXTERIOR - NON-SECURE AREA,
:                        AIRPORT EXTERIOR - SECURE AREA,AIRPORT PARKING LOT,
:                        AIRPORT TERMINAL LOWER LEVEL - NON-SECURE AREA,
:                        AIRPORT TERMINAL LOWER LEVEL - SECURE AREA,
:                        AIRPORT TERMINAL UPPER LEVEL - NON-SECURE AREA,
:                        AIRPORT TERMINAL UPPER LEVEL - SECURE AREA,
:                        ANIMAL HOSPITAL,APPLIANCE STORE,CHA APARTMENT,
:                        CHA HALLWAY/STAIRWELL/ELEVATOR,
:                        CHA PARKING LOT/GROUNDS,
:                        CHURCH/SYNAGOGUE/PLACE OF WORSHIP,
:                        COIN OPERATED MACHINE,CREDIT UNION,
:                        CTA GARAGE / OTHER PROPERTY,CTA TRACKS - RIGHT OF WAY,
:                        CTA TRAIN,DRIVEWAY - RESIDENTIAL,
:                        FACTORY/MANUFACTURING BUILDING,FIRE STATION,
:                        FOREST PRESERVE,HIGHWAY/EXPRESSWAY,
:                        OTHER RAILROAD PROP / TRAIN DEPOT,PAWN SHOP,POOL ROOM,
:                        RESIDENCE,RESIDENCE PORCH/HALLWAY,RESIDENCE-GARAGE,
:                        RESIDENTIAL YARD (FRONT/BACK),SAVINGS AND LOAN,
:                        SCHOOL PUBLIC BUILDING,SCHOOL PUBLIC GROUNDS,
:                        VACANT LOT/LAND,
:                        VEHICLE - DELIVERY TRUCK}: 8 (14667/12108)
location_description in {APARTMENT,CTA BUS,CURRENCY EXCHANGE,
:                        GAS STATION}: 3 (5871/4778)
location_description in {ALLEY,ATHLETIC CLUB,ATM (AUTOMATIC TELLER MACHINE),
:                        AUTO / BOAT / RV DEALERSHIP,BANK,BAR OR TAVERN,
:                        BARBERSHOP,BOAT/WATERCRAFT,BOWLING ALLEY,BRIDGE,
:                        CAR WASH,CEMETARY,CLEANING STORE,
:                        COLLEGE/UNIVERSITY GROUNDS,
:                        COLLEGE/UNIVERSITY RESIDENCE HALL,
:                        COMMERCIAL / BUSINESS OFFICE,CONSTRUCTION SITE,
:                        CONVENIENCE STORE,CTA BUS STOP,CTA PLATFORM,
:                        CTA STATION,DAY CARE CENTER,DEPARTMENT STORE,
:                        DRUG STORE,FEDERAL BUILDING,
:                        GOVERNMENT BUILDING/PROPERTY,GROCERY FOOD STORE,
:                        HOSPITAL BUILDING/GROUNDS,HOTEL/MOTEL,
:                        JAIL / LOCK-UP FACILITY,
:                        LAKEFRONT/WATERFRONT/RIVERBANK,LIBRARY,
:                        MEDICAL/DENTAL OFFICE,MOVIE HOUSE/THEATER,
:                        NURSING HOME/RETIREMENT HOME,OTHER,
:                        OTHER COMMERCIAL TRANSPORTATION,PARK PROPERTY,
:                        PARKING LOT/GARAGE(NON.RESID.),
:                        POLICE FACILITY/VEH PARKING LOT,RESTAURANT,
:                        SCHOOL PRIVATE BUILDING,SCHOOL PRIVATE GROUNDS,
:                        SIDEWALK,SMALL RETAIL STORE,SPORTS ARENA/STADIUM,
:                        STREET,TAVERN/LIQUOR STORE,TAXICAB,
:                        VEHICLE - OTHER RIDE SERVICE,
:                        VEHICLE - OTHER RIDE SHARE SERVICE (),
:                        VEHICLE NON-COMMERCIAL,VEHICLE-COMMERCIAL,WAREHOUSE}:
:...location_description in {ALLEY,CAR WASH,DAY CARE CENTER,
    :                        NURSING HOME/RETIREMENT HOME,SPORTS ARENA/STADIUM,
    :                        STREET,VEHICLE NON-COMMERCIAL}: 8 (17364/15004)
    location_description in {ATHLETIC CLUB,ATM (AUTOMATIC TELLER MACHINE),
                             AUTO / BOAT / RV DEALERSHIP,BANK,BAR OR TAVERN,
                             BARBERSHOP,BOAT/WATERCRAFT,BOWLING ALLEY,BRIDGE,
                             CEMETARY,CLEANING STORE,
                             COLLEGE/UNIVERSITY GROUNDS,
                             COLLEGE/UNIVERSITY RESIDENCE HALL,
                             COMMERCIAL / BUSINESS OFFICE,CONSTRUCTION SITE,
                             CONVENIENCE STORE,CTA BUS STOP,CTA PLATFORM,
                             CTA STATION,DEPARTMENT STORE,DRUG STORE,
                             FEDERAL BUILDING,GOVERNMENT BUILDING/PROPERTY,
                             GROCERY FOOD STORE,HOSPITAL BUILDING/GROUNDS,
                             HOTEL/MOTEL,JAIL / LOCK-UP FACILITY,
                             LAKEFRONT/WATERFRONT/RIVERBANK,LIBRARY,
                             MEDICAL/DENTAL OFFICE,MOVIE HOUSE/THEATER,OTHER,
                             OTHER COMMERCIAL TRANSPORTATION,PARK PROPERTY,
                             PARKING LOT/GARAGE(NON.RESID.),
                             POLICE FACILITY/VEH PARKING LOT,RESTAURANT,
                             SCHOOL PRIVATE BUILDING,SCHOOL PRIVATE GROUNDS,
                             SIDEWALK,SMALL RETAIL STORE,TAVERN/LIQUOR STORE,
                             TAXICAB,VEHICLE - OTHER RIDE SERVICE,
                             VEHICLE - OTHER RIDE SHARE SERVICE (),
                             VEHICLE-COMMERCIAL,WAREHOUSE}: 1 (7686/6506)


Evaluation on training data (45588 cases):

        Decision Tree   
      ----------------  
      Size      Errors  

         4 38396(84.2%)   <<


       (a)   (b)   (c)   (d)   (e)   (f)   (g)   (h)   (i)   (j)   (k)   (l)    <-classified as
      ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----
      1180    65                          1004                                  (a): class 1
       451  1093                          2304                                  (b): class 3
       582   611                          3429                                  (c): class 4
       402   308                          2987                                  (d): class 5
       613   878                          3080                                  (e): class 6
       354   584                          2820                                  (f): class 7
       896   438                          4919                                  (g): class 8
       648   420                          2969                                  (h): class 9
       548   773                          2873                                  (i): class 11
      1051    96                          1497                                  (j): class 18
       341   173                           835                                  (k): class 20
       620   432                          3314                                  (l): class 25


    Attribute usage:

    100.00% location_description


Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
Error in model.frame.default(object$Terms, newdata, na.action = na.action,  : 
  factor location_description has new levels FARM
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#deceptive_practice <- subset(deceptive_practice, select=-c(location_description))
#deceptive_practice_tr <- subset(deceptive_practice_tr, select=-c(location_description))

deceptive_practice_tr <- subset(deceptive_practice_tr, district=="19" | district == "4" | district == "25" | district=="2" | district == "24" |district == "1" | district == "18"| district == "20"  | district == "9" | district=="21" | district == "25" | district == "11" )

deceptive_practice <- subset(deceptive_practice, district=="19" | district == "4" | district == "25" | district=="2" | district == "24" |district == "1" | district == "18"| district == "20"  | district == "9" | district=="21" | district == "25" | district == "11" )

#train_c50<- subset(deceptive_practice_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#test_c50<- subset(deceptive_practice, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

crime_split_c50<- initial_split(subset(deceptive_practice_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)

#train_c50$location_description <- as.factor(train_c50$location_description)
#test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.5))  #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))
[1] "The classification error in test set is: 79.3173028417689 % 1230 correct classified cases from 5947"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 78.8584398117014 % 5030 correct classified cases from 23792"
#levels(chicago_crime$location_description)[1] = "None"
## Creating a training and test datasets
set.seed(1234)
#narcotics <- subset(narcotics, select=-c(location_description))
#narcotics_tr <- subset(narcotics_tr, select=-c(location_description))
#narcotics_tr <- subset(narcotics_tr, district=="10" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18")
#narcotics <- subset(narcotics, district=="10" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18")

#train_c50<- subset(narcotics_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
#test_c50<- subset(narcotics, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

crime_split_c50<- initial_split(subset(narcotics_tr, select=-c(location_description,case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
train_c50<- training(crime_split_c50)
test_c50<- testing(crime_split_c50)

#train_c50$location_description <- as.factor(train_c50$location_description)
#test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
#train_c50$arrest <- as.factor(train_c50$arrest)
#test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.01))  #Higher CF less prunning
summary(tree_result)

Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF = 0.01))


C5.0 [Release 2.07 GPL Edition]     Fri May  8 13:54:54 2020
-------------------------------

Class specified by attribute `outcome'

Read 16510 cases (3 attributes) from undefined.data

Decision tree:
 11 (16510/7867)


Evaluation on training data (16510 cases):

        Decision Tree   
      ----------------  
      Size      Errors  

         1 7867(47.6%)   <<


       (a)   (b)   (c)   (d)   (e)   (f)    <-classified as
      ----  ----  ----  ----  ----  ----
                         364                (a): class 1
                        1199                (b): class 8
                        3178                (c): class 10
                        8643                (d): class 11
                        2769                (e): class 15
                         357                (f): class 18


Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))
[1] "The classification error in test set is: 48.1948146353283 % 2138 correct classified cases from 4127"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 47.6499091459721 % 8643 correct classified cases from 16510"
## Creating a training and test datasets
set.seed(1234)
#robbery <- subset(robbery, select=-c(location_description))
#robbery_tr <- subset(robbery_tr, select=-c(location_description))
robbery_tr <- subset(robbery_tr, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4")
robbery <- subset(robbery, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4")

#robbery$location_description <- gsub("PARKING LOT","PARKING",robbery$location_description)
#robbery_tr$location_description <- gsub("PARKING LOT","PARKING",robbery_tr$location_description)
#robbery$location_description <- gsub("PARKINGGARAGE(NON.RESID.)","PARKING",robbery$location_description)
#robbery_tr$location_description <- gsub("PARKINGGARAGE(NON.RESID.)","PARKING",robbery_tr$location_description)

train_c50<- subset(robbery_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(robbery, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)

train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
train_c50$location_description <- factor(train_c50$location_description)
test_c50$location_description <- factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~., data=train_c50, control = C5.0Control(noGlobalPruning = TRUE, CF= 0.000001))  #Higher CF less prunning
summary(tree_result)

Call:
C5.0.formula(formula = district ~ ., data = train_c50, control = C5.0Control(noGlobalPruning = TRUE, CF = 1e-06))


C5.0 [Release 2.07 GPL Edition]     Wed May  6 17:02:50 2020
-------------------------------

Class specified by attribute `outcome'

Read 41594 cases (4 attributes) from undefined.data

Decision tree:

arrest = True:
:...location_description > 73:
:   :...location_description > 77:
:   :   :...location_description <= 85: 1 (1478/1201)
:   :   :   location_description > 85: 11 (738/598)
:   :   location_description <= 77:
:   :   :...location_description > 75: 8 (359/272)
:   :       location_description <= 75:
:   :       :...location_description <= 74: 5 (550/441)
:   :           location_description > 74: 11 (170/134)
:   location_description <= 73:
:   :...location_description > 54:
:       :...location_description > 66:
:       :   :...location_description <= 69: 1 (139/100)
:       :   :   location_description > 69: 6 (451/340)
:       :   location_description <= 66:
:       :   :...location_description > 56: 1 (648/338)
:       :       location_description <= 56:
:       :       :...location_description <= 55: 1 (2/1)
:       :           location_description > 55: 18 (101/38)
:       location_description <= 54:
:       :...location_description <= 37:
:           :...location_description > 12: 1 (885/655)
:           :   location_description <= 12:
:           :   :...location_description > 6: 6 (469/380)
:           :       location_description <= 6:
:           :       :...location_description <= 2: 5 (58/39)
:           :           location_description > 2: 8 (6)
:           location_description > 37:
:           :...location_description > 51: 11 (1040/784)
:               location_description <= 51:
:               :...location_description > 39: 1 (343/242)
:                   location_description <= 39:
:                   :...location_description <= 38: 1 (70/41)
:                       location_description > 38: 6 (297/185)
arrest = False:
:...location_description > 82: 11 (11217/9162)
    location_description <= 82:
    :...location_description > 70: 8 (11291/8218)
        location_description <= 70:
        :...location_description <= 11:
            :...location_description <= 9: 11 (1201/932)
            :   location_description > 9: 6 (4744/3827)
            location_description > 11:
            :...location_description <= 25:
                :...location_description > 22: 5 (188/108)
                :   location_description <= 22:
                :   :...location_description > 17: 8 (85/69)
                :       location_description <= 17:
                :       :...location_description <= 16: 1 (139/102)
                :           location_description > 16: 18 (60/32)
                location_description > 25:
                :...location_description > 63: 8 (1904/1546)
                    location_description <= 63:
                    :...location_description > 54:
                        :...location_description <= 58: 18 (159/89)
                        :   location_description > 58: 11 (67/53)
                        location_description <= 54:
                        :...location_description > 46: 11 (660/489)
                            location_description <= 46:
                            :...location_description > 36: 1 (904/637)
                                location_description <= 36:
                                :...location_description > 32: 11 (584/482)
                                    location_description <= 32:
                                    :...location_description > 28: 18 (473/350)
                                        location_description <= 28:
                                        :...location_description <= 26: 11 (91/75)
                                            location_description > 26: 8 (23/13)


Evaluation on training data (41594 cases):

        Decision Tree   
      ----------------  
      Size      Errors  

        35 31973(76.9%)   <<


       (a)   (b)   (c)   (d)   (e)   (f)   (g)   (h)   (i)    <-classified as
      ----  ----  ----  ----  ----  ----  ----  ----  ----
      1291          28   249   649        1145         173    (a): class 1
       341         102  1023  1905        1586          64    (b): class 4
       315         208   314  1598        1344          36    (c): class 5
       450          90  1229  1796        2295          61    (d): class 6
       390          90   666  3550        1944          64    (e): class 8
       416          80   722  1601        1497          42    (f): class 9
       435          99   799  1081        3059          44    (g): class 11
       184          45   574   699        1652          25    (h): class 15
       786          54   385   789        1246         284    (i): class 18


    Attribute usage:

    100.00% location_description
    100.00% arrest


Time: 0.0 secs
#Plotting the tree
plot(tree_result,subtree=NULL)


## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))
[1] "The classification error in test set is: 82.5898772193269 % 1971 correct classified cases from 11321"
pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
[1] "The classification error in train set is: 76.8692599894216 % 9621 correct classified cases from 41594"
## Creating a training and test datasets
set.seed(1234)
theft <- subset(theft, select=-c(location_description))
theft_tr <- subset(theft_tr, select=-c(location_description))
theft_tr <- subset(theft_tr, district=="19" | district == "1" | district=="18"| district=="24" | district == "5" | district=="4")
theft <- subset(theft, district=="19" | district == "1" | district=="18"| district=="24" | district == "5" | district=="4")

train_c50<- subset(theft_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(theft, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)

train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
#train_c50$arrest <- as.factor(train_c50$arrest)
#test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.01))  #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))

pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
set.seed(1234)
#violent_crime <- subset(violent_crime, select=-c(location_description))
#violent_tr_crime <- subset(violent_tr_crime, select=-c(location_description))
violent_tr_crime <- subset(violent_tr_crime, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4" | district == "19"| district == "20"  | district == "10" | district=="21" | district == "25" | district == "2")
violent_crime <- subset(violent_crime, district=="6" | district == "11" | district == "15" | district=="8" | district == "1" | district=="18"| district=="9" | district == "5" | district=="4" | district == "19"| district == "20"  | district == "10" | district=="21" | district == "25" | district == "2")

train_c50<- subset(violent_tr_crime, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(violent_crime, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)

train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
#train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
#test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
train_c50$arrest <- as.factor(train_c50$arrest)
test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, trials = 10,control = C5.0Control(noGlobalPruning = FALSE, CF= 0.000001))  #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL,trial=9)
Only 1 trials are in the model. Setting 'trial' to 0 (the plot code is zero-based).

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")
Error in model.frame.default(object$Terms, newdata, na.action = na.action,  : 
  factor location_description has new levels , ATM (AUTOMATIC TELLER MACHINE), CHA PLAY LOT, HORSE STABLE, TRAILER, VEHICLE - DELIVERY TRUCK, VEHICLE-COMMERCIAL - TROLLEY BUS
set.seed(1234)
#weapons_violation <- subset(weapons_violation, select=-c(location_description))
#weapons_violation_tr <- subset(weapons_violation_tr, select=-c(location_description))
weapons_violation_tr <- subset(weapons_violation_tr, district=="6" | district == "11" | district == "7" | district=="8" | district == "1" | district=="18" | district == "5" | district=="4")
weapons_violation <- subset(weapons_violation, district=="6" | district == "11" | district == "7" | district=="8" | district == "1" | district=="18" | district == "5" | district=="4")

train_c50<- subset(weapons_violation_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude))
test_c50<- subset(weapons_violation, select=-c(case_number,block,ward,description,day,month,latitude,longitude))

#crime_split_c50<- initial_split(subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,description,day,month,latitude,longitude)), prop=0.8)
#train_c50<- training(crime_split_c50)
#test_c50<- testing(crime_split_c50)

train_c50$location_description <- as.factor(train_c50$location_description)
test_c50$location_description <- as.factor(test_c50$location_description)
#train_c50$arrest <- as.numeric(train_c50$arrest, unique(train_c50$arrest))
#test_c50$arrest <- as.numeric(test_c50$arrest, unique(test_c50$arrest))
#train_c50$primary_type <- as.numeric(train_c50$primary_type, unique(train_c50$primary_type))
#test_c50$primary_type <- as.numeric(test_c50$primary_type, unique(test_c50$primary_type))
train_c50$location_description <- as.numeric(train_c50$location_description, unique(train_c50$location_description))
test_c50$location_description <- as.numeric(test_c50$location_description, unique(test_c50$location_description))
#train_c50$district <- as.numeric(train_c50$district, unique(train_c50$district))
#test_c50$district <- as.numeric(test_c50$district, unique(test_c50$district))
#train_c50$arrest <- as.factor(train_c50$arrest)
#test_c50$arrest <- as.factor(test_c50$arrest)
train_c50$district <- as.factor(train_c50$district)
test_c50$district <- as.factor(test_c50$district)
train_c50$district <- factor(train_c50$district)
test_c50$district <- factor(test_c50$district)
#train_c50$primary_type <- as.factor(train_c50$primary_type)
#test_c50$primary_type <- as.factor(test_c50$primary_type)


#Creating the decision tree algorithm C4.5 
tree_result <- C5.0(district  ~ ., data=train_c50, control = C5.0Control(noGlobalPruning = FALSE, CF= 0.01))  #Higher CF less prunning
#summary(tree_result)
#Plotting the tree
plot(tree_result,subtree=NULL)

## PREDICTION
#Prediction of new cases from the test dataset
predictions <- predict(tree_result, newdata = test_c50, type ="class")

#table(prediction=predictions, real= crime_test_c50$primary_type)
#crime_test_c50$primary_type <- factor(crime_test_c50$primary_type)
error_classification <- mean(predictions != test_c50$district)

paste("The classification error in test set is:", 100*error_classification, "%",
      sum(predictions==test_c50$district),
      "correct classified cases from", length(predictions))

pred_train <- predict(tree_result, newdata = train_c50)
#confusionMatrix(pred_train, crime_train$district)
#pred_train<-round(pred_train)
#table(prediction=pred_train, real= crime_train_c50$arrest)

error_classification <- mean(pred_train != train_c50$district)

paste("The classification error in train set is:", 100*error_classification, "%",
      sum(pred_train==train_c50$district),
      "correct classified cases from", length(pred_train))
#Tunning the m number of predictors
tuning_rf_mtry <- function(df, y, ntree = 100){
  
  require(dplyr)
  max_predictors <- ncol(df) - 1
  n_predictors   <- rep(NA, max_predictors)
  oob_err_rate   <- rep(NA, max_predictors)
  for (i in 1:max_predictors) {
    set.seed(123)
    f <- formula(paste(y,"~ ."))
    model_rf <- randomForest(formula = f, data = df, mtry = i, ntree = ntree)
    n_predictors[i] <- i
    oob_err_rate[i] <- tail(model_rf$err.rate[,1], n = 1)
  }
  results <- data_frame(n_predictors, oob_err_rate)
  return(results)
}

hiperparameter_mtry <-  tuning_rf_mtry(df = RF_train, y = "primary_type")
Error in oob_err_rate[i] <- tail(model_rf$err.rate[, 1], n = 1) : 
  replacement has length zero

REDES NEURONALES

## REDES
chicago_crime_nn <- subset(chicago_crime_subset, select=-c(case_number,block,ward,day,latitude,longitude))
chicago_crime_nn_tr <- subset(chicago_crime_subset_tr, select=-c(case_number,block,ward,day,latitude,longitude))

library(kohonen) # for building the SOM map
library(caret)     #for confusion matrix

#Extracting target variable
target_train <- chicago_crime_nn_tr$primary_type
chicago_crime_nn_tr <- subset(chicago_crime_nn_tr, select=-c(primary_type))

target_test <- chicago_crime_nn$primary_type
chicago_crime_nn <- subset(chicago_crime_nn, select=-c(primary_type))

chicago_crime_nn_tr$arrest <- as.factor(chicago_crime_nn_tr$arrest)
chicago_crime_nn_tr$arrest <- as.numeric(chicago_crime_nn_tr$arrest)
#chicago_crime$primary_type <- as.numeric(chicago_crime$primary_type)
chicago_crime_nn_tr$district <- as.numeric(chicago_crime_nn_tr$district)
#chicago_crime_nn_tr$district <- as.factor(chicago_crime_nn_tr$district)
chicago_crime_nn_tr$description <- as.factor(chicago_crime_nn_tr$description)
chicago_crime_nn_tr$description <- as.numeric(chicago_crime_nn_tr$description)
chicago_crime_nn_tr$location_description <- as.factor(chicago_crime_nn_tr$location_description)
chicago_crime_nn_tr$location_description <- as.numeric(chicago_crime_nn_tr$location_description)
chicago_crime_nn_tr$month <- as.numeric(chicago_crime_nn_tr$month)
#chicago_crime_nn_tr$month <- as.factor(chicago_crime_nn_tr$month)

chicago_crime_nn$arrest <- as.factor(chicago_crime_nn$arrest)
chicago_crime_nn$arrest <- as.numeric(chicago_crime_nn$arrest)
#chicago_crime_nn$primary_type <- as.numeric(chicago_crime_nn$primary_type)
chicago_crime_nn$district <- as.numeric(chicago_crime_nn$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
chicago_crime_nn$description <- as.factor(chicago_crime_nn$description)
chicago_crime_nn$description <- as.numeric(chicago_crime_nn$description)
chicago_crime_nn$location_description <- as.factor(chicago_crime_nn$location_description)
chicago_crime_nn$location_description <- as.numeric(chicago_crime_nn$location_description)
chicago_crime_nn$month <- as.numeric(chicago_crime_nn$month)
#chicago_crime_nn$month <- as.factor(chicago_crime_nn$month)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
train <- chicago_crime_nn_tr[index,]
test <- chicago_crime_nn_tr[-index,]

#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)

#train_label<-target_train
#test_label<-target_test
train_label<-target_train[index]
test_label<-target_train[-index]

#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")

#training the map
crime.som <- som(train[1:100000,], grid=som_grid, 
               rlen=100, alpha=c(0.05, 0.01), 
               radius= 2, keep.data=T)

# Names of the variables used
colnames(train)
[1] "description"          "location_description" "arrest"               "district"             "month"               
# main characteristics of the map
summary(crime.som)
SOM of size 8x8 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 100000 objects.
Mean distance to the closest unit in the map: 78.082.
#Showing the training process
plot(crime.som, type="changes")


#node counts
plot(crime.som, type="counts", main="Examples per Neuron")


#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")

coolBlueHOtRed<-function(n, alpha=1){rainbow(n,end=4/6, 
                                             alpha=alpha)[n:1]}
par(mfrow=c(2,3))

plot(crime.som, type="property", property=getCodes(crime.som, 1)[,1],
     main=colnames(getCodes(crime.som, 1))[1],
     palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,2],
     main=colnames(getCodes(crime.som, 1))[2],
     palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,3],
     main=colnames(getCodes(crime.som, 1))[3],
     palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,4],
     main=colnames(getCodes(crime.som, 1))[4],
     palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,5],
     main=colnames(getCodes(crime.som, 1))[5],
     palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,6],
#     main=colnames(getCodes(crime.som, 1))[6],
#     palette.name=coolBlueHOtRed)

# Alternative easier
coolBlueHotRed<-function(n, alpha=1){rainbow(n,end=4/6, 
                                             alpha=alpha)[n:1]}

par(mfrow=c(5,3))

for (j in 1:ncol(train)) {
plot(crime.som, type="property", property=crime.som$codes[[1]][,j],
     palette.name=coolBlueHotRed,
     main=colnames(train)[j], cex=0.5)
}


#som.prediction <- predict(crime.som, test)
#Clustering patterns in the map
groups<-8
#Applying hierarchical clustering for grouping patterns
crime.hc=cutree(hclust(dist(crime.som$codes[[1]])), groups)
plot(crime.som, type="codes", bgcol = rainbow(groups)[crime.hc],
     main="clustering the patterns discovered")
add.cluster.boundaries(crime.som,crime.hc)


#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
#index <- sample(nrow(target_train.sc), round(0.75*nrow(crime.sc)))
#train <- target_train.sc
#test <- target_test.sc

#train <- chicago_crime_nn_tr
#test <- chicago_crime_nn
#index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
#train <- chicago_crime_nn_tr[index,]
#test <- chicago_crime_nn_tr[-index,]
#train_label<-target_train
#test_label<-target_test

#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train[1:100000,], train_label[1:100000],
              grid=som_grid, 
              rlen=100, alpha=c(0.05, 0.01), 
              radius= 2, keep.data=T)

#Showing the training process
plot(kohmap, type="changes")


#Showing distribution of wine labels in neurons
plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c("Crime"))


plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c(" patterns"))


# Plotting classes in neurons
plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
     col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)


#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics

                    
train_label          ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY  THEFT VIOLENT CRIME WEAPONS VIOLATION
  ASSAULT               4120               0                 15         0    1442   3264         23831                 0
  CRIMINAL DAMAGE        327           52639               1472         2    3088    322           259               120
  DECEPTIVE PRACTICE     246             458              10222         0    9272  14838          4850                24
  NARCOTICS               94               0                206     16574     621   9233          1396                 0
  ROBBERY                555           17038               1937         0   30716   8157          8735               688
  THEFT                  130            1345               1644         0    2375 142814         12255                 0
  VIOLENT CRIME         4098              56                894        70    1847   7334         45993                20
  WEAPONS VIOLATION       78            3119                  1        84    1459     93           774              4591

Overall Statistics
                                          
               Accuracy : 0.672           
                 95% CI : (0.6706, 0.6734)
    No Information Rate : 0.4064          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.5821          
                                          
 Mcnemar's Test P-Value : < 2.2e-16       

Statistics by Class:

                     Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity                0.427032                 0.7051                   0.62363          0.99068        0.60441       0.7676
Specificity                0.936294                 0.9854                   0.93275          0.97382        0.90882       0.9347
Pos Pred Value             0.126102                 0.9040                   0.25613          0.58932        0.45286       0.8895
Neg Pred Value             0.986998                 0.9449                   0.98524          0.99964        0.94845       0.8545
Prevalence                 0.021073                 0.1631                   0.03580          0.03654        0.11100       0.4064
Detection Rate             0.008999                 0.1150                   0.02233          0.03620        0.06709       0.3119
Detection Prevalence       0.071362                 0.1272                   0.08717          0.06143        0.14815       0.3507
Balanced Accuracy          0.681663                 0.8453                   0.77819          0.98225        0.75662       0.8511
                     Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity                        0.4689                  0.84347
Specificity                        0.9602                  0.98760
Pos Pred Value                     0.7626                  0.45014
Neg Pred Value                     0.8689                  0.99810
Prevalence                         0.2143                  0.01189
Detection Rate                     0.1005                  0.01003
Detection Prevalence               0.1317                  0.02228
Balanced Accuracy                  0.7145                  0.91554
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics

                    
test_label           ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
  ASSAULT               1293               0                 11         0     482  1117          7937                 0
  CRIMINAL DAMAGE        100           17536                532         0    1044    86            93                38
  DECEPTIVE PRACTICE      79             146               3319         0    3092  5130          1598                 6
  NARCOTICS               33               0                 74      5598     207  3013           466                 0
  ROBBERY                219            5663                632         0   10195  2713          2872               242
  THEFT                   51             430                567         0     831 47387          4179                 0
  VIOLENT CRIME         1374              21                310        17     624  2447         15460                 9
  WEAPONS VIOLATION       35            1015                  0        24     507    28           224              1506

Overall Statistics
                                          
               Accuracy : 0.6703          
                 95% CI : (0.6679, 0.6726)
    No Information Rate : 0.4057          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.58            
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity                0.406093                 0.7068                   0.60955          0.99273         0.6003       0.7653
Specificity                0.936110                 0.9852                   0.93170          0.97419         0.9090       0.9332
Pos Pred Value             0.119280                 0.9026                   0.24824          0.59610         0.4524       0.8866
Neg Pred Value             0.986662                 0.9454                   0.98473          0.99971         0.9478       0.8534
Prevalence                 0.020863                 0.1626                   0.03568          0.03695         0.1113       0.4057
Detection Rate             0.008472                 0.1149                   0.02175          0.03668         0.0668       0.3105
Detection Prevalence       0.071030                 0.1273                   0.08761          0.06154         0.1477       0.3502
Balanced Accuracy          0.671101                 0.8460                   0.77063          0.98346         0.7547       0.8492
                     Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity                        0.4709                 0.836202
Specificity                        0.9599                 0.987846
Pos Pred Value                     0.7630                 0.451033
Neg Pred Value                     0.8688                 0.998024
Prevalence                         0.2151                 0.011801
Detection Rate                     0.1013                 0.009868
Detection Prevalence               0.1328                 0.021879
Balanced Accuracy                  0.7154                 0.912024
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics

                    
test_label           ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
  ASSAULT               1293               0                 11         0     482  1117          7937                 0
  CRIMINAL DAMAGE        100           17536                532         0    1044    86            93                38
  DECEPTIVE PRACTICE      79             146               3319         0    3092  5130          1598                 6
  NARCOTICS               33               0                 74      5598     207  3013           466                 0
  ROBBERY                219            5663                632         0   10195  2713          2872               242
  THEFT                   51             430                567         0     831 47387          4179                 0
  VIOLENT CRIME         1374              21                310        17     624  2447         15460                 9
  WEAPONS VIOLATION       35            1015                  0        24     507    28           224              1506

Overall Statistics
                                          
               Accuracy : 0.6703          
                 95% CI : (0.6679, 0.6726)
    No Information Rate : 0.4057          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.58            
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity                0.406093                 0.7068                   0.60955          0.99273         0.6003       0.7653
Specificity                0.936110                 0.9852                   0.93170          0.97419         0.9090       0.9332
Pos Pred Value             0.119280                 0.9026                   0.24824          0.59610         0.4524       0.8866
Neg Pred Value             0.986662                 0.9454                   0.98473          0.99971         0.9478       0.8534
Prevalence                 0.020863                 0.1626                   0.03568          0.03695         0.1113       0.4057
Detection Rate             0.008472                 0.1149                   0.02175          0.03668         0.0668       0.3105
Detection Prevalence       0.071030                 0.1273                   0.08761          0.06154         0.1477       0.3502
Balanced Accuracy          0.671101                 0.8460                   0.77063          0.98346         0.7547       0.8492
                     Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity                        0.4709                 0.836202
Specificity                        0.9599                 0.987846
Pos Pred Value                     0.7630                 0.451033
Neg Pred Value                     0.8688                 0.998024
Prevalence                         0.2151                 0.011801
Detection Rate                     0.1013                 0.009868
Detection Prevalence               0.1328                 0.021879
Balanced Accuracy                  0.7154                 0.912024
## REDES
chicago_crime_nn2 <- subset(chicago_crime_subset, select=-c(description,case_number,block,day,latitude,longitude))
chicago_crime_nn_tr2 <- subset(chicago_crime_subset_tr, select=-c(description,case_number,block,day,latitude,longitude))

library(kohonen) # for building the SOM map
library(caret)     #for confusion matrix

#Extracting target variable
target_train2 <- chicago_crime_nn_tr2$primary_type
chicago_crime_nn_tr2 <- subset(chicago_crime_nn_tr2, select=-c(primary_type))

target_test2 <- chicago_crime_nn2$primary_type
chicago_crime_nn2 <- subset(chicago_crime_nn2, select=-c(primary_type))

chicago_crime_nn_tr2$arrest <- as.factor(chicago_crime_nn_tr2$arrest)
chicago_crime_nn_tr2$arrest <- as.numeric(chicago_crime_nn_tr2$arrest)
#chicago_crime$primary_type <- as.numeric(chicago_crime$primary_type)
chicago_crime_nn_tr2$district <- as.numeric(chicago_crime_nn_tr2$district)
#chicago_crime_nn_tr$district <- as.factor(chicago_crime_nn_tr$district)
#chicago_crime_nn_tr2$description <- as.factor(chicago_crime_nn_tr2$description)
#chicago_crime_nn_tr2$description <- as.numeric(chicago_crime_nn_tr2$description)
chicago_crime_nn_tr2$location_description <- as.factor(chicago_crime_nn_tr2$location_description)
chicago_crime_nn_tr2$location_description <- as.numeric(chicago_crime_nn_tr2$location_description)
chicago_crime_nn_tr2$month <- as.numeric(chicago_crime_nn_tr2$month)
chicago_crime_nn_tr$month <- as.factor(chicago_crime_nn_tr$month)

chicago_crime_nn2$arrest <- as.factor(chicago_crime_nn2$arrest)
chicago_crime_nn2$arrest <- as.numeric(chicago_crime_nn2$arrest)
#chicago_crime_nn$primary_type <- as.numeric(chicago_crime_nn$primary_type)
chicago_crime_nn2$district <- as.numeric(chicago_crime_nn2$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
#chicago_crime_nn2$description <- as.factor(chicago_crime_nn2$description)
#chicago_crime_nn2$description <- as.numeric(chicago_crime_nn2$description)
chicago_crime_nn2$location_description <- as.factor(chicago_crime_nn2$location_description)
chicago_crime_nn2$location_description <- as.numeric(chicago_crime_nn2$location_description)
chicago_crime_nn2$month <- as.numeric(chicago_crime_nn2$month)
chicago_crime_nn$month <- as.factor(chicago_crime_nn$month)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
index <- sample(nrow(chicago_crime_nn_tr2), round(0.75*nrow(chicago_crime_nn_tr2)))
train <- chicago_crime_nn_tr2[index,]
test <- chicago_crime_nn_tr2[-index,]

#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)

#train_label<-target_train
#test_label<-target_test
train_label<-target_train2[index]
test_label<-target_train2[-index]

#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")

#training the map
crime.som <- som(train[1:100000,], grid=som_grid, 
               rlen=100, alpha=c(0.05, 0.01), 
               radius= 2, keep.data=T)

# Names of the variables used
colnames(train)
[1] "location_description" "arrest"               "district"             "ward"                 "month"               
# main characteristics of the map
summary(crime.som)
SOM of size 8x8 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 100000 objects.
Mean distance to the closest unit in the map: 31.207.
#Showing the training process
plot(crime.som, type="changes")


#node counts
plot(crime.som, type="counts", main="Examples per Neuron")


#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")

coolBlueHOtRed<-function(n, alpha=1){rainbow(n,end=4/6, 
                                             alpha=alpha)[n:1]}
par(mfrow=c(2,3))

plot(crime.som, type="property", property=getCodes(crime.som, 1)[,1],
     main=colnames(getCodes(crime.som, 1))[1],
     palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,2],
     main=colnames(getCodes(crime.som, 1))[2],
     palette.name=coolBlueHOtRed)
plot(crime.som, type="property", property=getCodes(crime.som, 1)[,3],
     main=colnames(getCodes(crime.som, 1))[3],
     palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,4],
#     main=colnames(getCodes(crime.som, 1))[4],
#     palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,5],
#     main=colnames(getCodes(crime.som, 1))[5],
#     palette.name=coolBlueHOtRed)
#plot(crime.som, type="property", property=getCodes(crime.som, 1)[,6],
#     main=colnames(getCodes(crime.som, 1))[6],
#     palette.name=coolBlueHOtRed)

# Alternative easier
coolBlueHotRed<-function(n, alpha=1){rainbow(n,end=4/6, 
                                             alpha=alpha)[n:1]}

par(mfrow=c(5,3))

for (j in 1:ncol(train)) {
plot(crime.som, type="property", property=crime.som$codes[[1]][,j],
     palette.name=coolBlueHotRed,
     main=colnames(train)[j], cex=0.5)
}

#Clustering patterns in the map
library(RColorBrewer)
groups<-8
#Applying hierarchical clustering for grouping patterns
crime.hc=cutree(hclust(dist(crime.som$codes[[1]])), groups)
plot(crime.som, type="codes", bgcol = brewer.pal(groups, name="YlGnBu")[crime.hc],
     main="clustering the patterns discovered")
add.cluster.boundaries(crime.som,crime.hc)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
#index <- sample(nrow(target_train.sc), round(0.75*nrow(crime.sc)))
#train <- target_train.sc
#test <- target_test.sc

#train <- chicago_crime_nn_tr
#test <- chicago_crime_nn
#index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
#train <- chicago_crime_nn_tr[index,]
#test <- chicago_crime_nn_tr[-index,]
#train_label<-target_train
#test_label<-target_test

#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train[1:100000,], train_label[1:100000],
              grid=som_grid, 
              rlen=100, alpha=c(0.05, 0.01), 
              radius= 2, keep.data=T)

#Showing the training process
plot(kohmap, type="changes")


#Showing distribution of wine labels in neurons
plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c("Crime"))


plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c(" patterns"))


# Plotting classes in neurons
#plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
#     col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)

#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics

                    
train_label          ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY  THEFT VIOLENT CRIME WEAPONS VIOLATION
  ASSAULT                  0               0                327      1453    5590  22496          2806                 0
  CRIMINAL DAMAGE          0               0                853       663   11935  44081           697                 0
  DECEPTIVE PRACTICE       0               0               2343       640    8667  27933           327                 0
  NARCOTICS                0               0                 87      5353    3029  18090          1565                 0
  ROBBERY                  0               0               1297      2509   16747  44776          2497                 0
  THEFT                    0               0               1322      1954   12329 142118          2840                 0
  VIOLENT CRIME            0               0                590      3873   10745  39590          5514                 0
  WEAPONS VIOLATION        0               0                 31       649    1778   7098           643                 0

Overall Statistics
                                          
               Accuracy : 0.3758          
                 95% CI : (0.3744, 0.3772)
    No Information Rate : 0.7561          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.1127          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity                      NA                     NA                  0.342044          0.31315        0.23647       0.4105
Specificity                 0.92864                 0.8728                  0.916700          0.94833        0.86802       0.8348
Pos Pred Value                   NA                     NA                  0.058707          0.19034        0.24691       0.8851
Neg Pred Value                   NA                     NA                  0.989216          0.97268        0.86135       0.3135
Prevalence                  0.00000                 0.0000                  0.014962          0.03734        0.15468       0.7561
Detection Rate              0.00000                 0.0000                  0.005118          0.01169        0.03658       0.3104
Detection Prevalence        0.07136                 0.1272                  0.087171          0.06143        0.14815       0.3507
Balanced Accuracy                NA                     NA                  0.629372          0.63074        0.55225       0.6227
                     Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity                       0.32648                       NA
Specificity                       0.87573                  0.97772
Pos Pred Value                    0.09142                       NA
Neg Pred Value                    0.97139                       NA
Prevalence                        0.03689                  0.00000
Detection Rate                    0.01204                  0.00000
Detection Prevalence              0.13173                  0.02228
Balanced Accuracy                 0.60111                       NA
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics

                    
test_label           ASSAULT CRIMINAL DAMAGE DECEPTIVE PRACTICE NARCOTICS ROBBERY THEFT VIOLENT CRIME WEAPONS VIOLATION
  ASSAULT                  0               0                 91       514    1938  7375           922                 0
  CRIMINAL DAMAGE          0               0                300       221    3912 14800           196                 0
  DECEPTIVE PRACTICE       0               0                763       219    3003  9284           101                 0
  NARCOTICS                0               0                 44      1846     972  6030           499                 0
  ROBBERY                  0               0                413       849    5544 14908           822                 0
  THEFT                    0               0                425       680    4163 47221           956                 0
  VIOLENT CRIME            0               0                185      1277    3599 13357          1844                 0
  WEAPONS VIOLATION        0               0                 15       244     583  2289           208                 0

Overall Statistics
                                          
               Accuracy : 0.3749          
                 95% CI : (0.3725, 0.3774)
    No Information Rate : 0.7553          
    P-Value [Acc > NIR] : 1               
                                          
                  Kappa : 0.1122          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: ASSAULT Class: CRIMINAL DAMAGE Class: DECEPTIVE PRACTICE Class: NARCOTICS Class: ROBBERY Class: THEFT
Sensitivity                      NA                     NA                   0.34123          0.31556        0.23379       0.4097
Specificity                 0.92897                 0.8727                   0.91616          0.94859        0.86817       0.8334
Pos Pred Value                   NA                     NA                   0.05707          0.19657        0.24601       0.8835
Neg Pred Value                   NA                     NA                   0.98942          0.97204        0.86031       0.3139
Prevalence                  0.00000                 0.0000                   0.01465          0.03833        0.15539       0.7553
Detection Rate              0.00000                 0.0000                   0.00500          0.01210        0.03633       0.3094
Detection Prevalence        0.07103                 0.1273                   0.08761          0.06154        0.14767       0.3502
Balanced Accuracy                NA                     NA                   0.62870          0.63207        0.55098       0.6215
                     Class: VIOLENT CRIME Class: WEAPONS VIOLATION
Sensitivity                       0.33237                       NA
Specificity                       0.87476                  0.97812
Pos Pred Value                    0.09101                       NA
Neg Pred Value                    0.97201                       NA
Prevalence                        0.03635                  0.00000
Detection Rate                    0.01208                  0.00000
Detection Prevalence              0.13277                  0.02188
Balanced Accuracy                 0.60357                       NA
## REDES
narcotics_nn <- subset(narcotics_tr, select=-c(case_number,block,day,latitude,longitude))

library(kohonen) # for building the SOM map
library(caret)     #for confusion matrix

#Extracting target variable
target_train <- narcotics_nn$district
narcotics_nn <- subset(narcotics_nn, select=-c(district))

narcotics_nn$arrest <- as.factor(narcotics_nn$arrest)
narcotics_nn$arrest <- as.numeric(narcotics_nn$arrest)
narcotics_nn$primary_type <- as.factor(narcotics_nn$primary_type)
narcotics_nn$primary_type <- as.numeric(narcotics_nn$primary_type)
#narcotics_nn$district <- as.numeric(narcotics_nn$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
narcotics_nn$description <- as.factor(narcotics_nn$description)
narcotics_nn$description <- as.numeric(narcotics_nn$description)
narcotics_nn$location_description <- as.factor(narcotics_nn$location_description)
narcotics_nn$location_description <- as.numeric(narcotics_nn$location_description)
narcotics_nn$month <- as.numeric(narcotics_nn$month)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
index <- sample(nrow(narcotics_nn), round(0.75*nrow(narcotics_nn)))
train <- narcotics_nn[index,]
test <- narcotics_nn[-index,]

#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)

#train_label<-target_train
#test_label<-target_test
train_label<-target_train[index]
test_label<-target_train[-index]

#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")

#training the map
crime.som <- som(train, grid=som_grid, 
               rlen=100, alpha=c(0.05, 0.01), 
               radius= 2, keep.data=T)

# Names of the variables used
colnames(train)
[1] "primary_type"         "description"          "location_description" "arrest"               "ward"                
[6] "month"               
# main characteristics of the map
summary(crime.som)
SOM of size 8x8 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 28136 objects.
Mean distance to the closest unit in the map: 27.532.
#Showing the training process
plot(crime.som, type="changes")


#node counts
plot(crime.som, type="counts", main="Examples per Neuron")


#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
#index <- sample(nrow(target_train.sc), round(0.75*nrow(crime.sc)))
#train <- target_train.sc
#test <- target_test.sc

#train <- chicago_crime_nn_tr
#test <- chicago_crime_nn
#index <- sample(nrow(chicago_crime_nn_tr), round(0.75*nrow(chicago_crime_nn_tr)))
#train <- chicago_crime_nn_tr[index,]
#test <- chicago_crime_nn_tr[-index,]
#train_label<-target_train
#test_label<-target_test

#main characteristics of the map
som_grid<-somgrid(xdim=8, ydim=8, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train, train_label,
              grid=som_grid, 
              rlen=100, alpha=c(0.05, 0.01), 
              radius= 2, keep.data=T)

#Showing the training process
plot(kohmap, type="changes")


#Showing distribution of wine labels in neurons
plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c("Crime"))


plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c(" patterns"))


# Plotting classes in neurons
#plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
#     col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)

#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics

           
train_label    1    2    3    4    5    6    7    8    9   10   11   12   14   15   16   17   18   19   20   22   24   25   31
         1    34   28    0  127    0   17   25    7    0    0   13    0    0   19   28    0   32   16    0    0   14    0    0
         2    11  163    6  200    0   23  102   31    0   30    4    0    0    0    0    0    1    0    0    0    0    0    0
         3     6   98   28  215    0   26  174   32    0  205   42    0    0    0    0    0    1    0    0    0    0    0    0
         4    11  103    0  458    0   24  438   19  125    0    3    0    0    0    0    0    2    0    0    0    0    0    0
         5    22    3    2  190   23   27  283   14   90   26  135    0    0  119   15    0    2    0    0    0    3  127    0
         6    12   69   22  242    0   95  552   43   31  326  178    0    0    0    0    0    2    0    0    0    0    2    0
         7    18   61    0  104    0   45 1282   51  183  139  231    0    0    0    0    0    0    0    0    0    0    1    0
         8     3    0    0    5    0    9  527   55  216  179  147    0    0    0    0    0    0    0    0    0    0    4    0
         9    12   28    8   33    0   23  477   24  306  115   81    0    0    0    0    0    0    0    0    0    0    0    0
         10    3    0   11    3    0   10   69   55   35 1749 1059    0    0    3    0    0    1    0    0    0    0    5    0
         11    1   66    4   98    2    1   85   54    0 1094 6437    0    0  120   47    0    2    2    0    0    9   52    0
         12   24   55    0  102    0   16   41   10    0   55  321    0    0    7    2    0    2    0    0    0    1    7    0
         14    1   19    0   28    5    4   22    5    0   17   79    0    0   15    2    0    0    2    0    0    0   30    0
         15    0    0    1    0    6    0   16    4    0  186 1547    0    0  563   65    0    3   10    0    0   17  176    0
         16    0    0    0    0    0    0    0    1    0    0   83    0    0   45  248    0   29   22    0    0   55   82    0
         17    0    0    0    0    0    0    1    0    0    0   31    0    0   56   31    0    5   16    0    0   15  100    0
         18    0    1    0    2    1    0    1    0    0    5   95    0    0   39   62    0   69   26    0    0   38    8    0
         19    0    1    0    1    0    0    2    0    0    0    9    0    0   15   53    0   29   77    0    0  111    5    0
         20    0    0    0    0    0    0    0    0    0    0    6    0    0   14   29    0   28   34    0    0   67   19    0
         22    0    0   17    4   10   12   17    4    2  176  124    0    0   44    3    0    0    0    0    0    0   56    0
         24    0    0    0    0    0    0    0    0    0    0    1    0    0    3   47    0   21   40    0    0  173    4    0
         25    0    0    0    0   11    0    4    1    0   22  553    0    0  243   34    0    1   18    0    0   19  299    0
         31    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0

Overall Statistics
                                          
               Accuracy : 0.4286          
                 95% CI : (0.4228, 0.4344)
    No Information Rate : 0.3973          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.3245          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: 1 Class: 2  Class: 3 Class: 4  Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity          0.215190 0.234532 0.2828283  0.25276 0.3965517 0.286145  0.31132 0.134146  0.30972   0.40449    0.5758        NA
Specificity          0.988348 0.985132 0.9715019  0.97246 0.9623193 0.946806  0.96532 0.960687  0.97050   0.94734    0.9035   0.97715
Pos Pred Value       0.094444 0.285464 0.0338573  0.38715 0.0212766 0.060356  0.60615 0.048035  0.27642   0.58242    0.7973        NA
Neg Pred Value       0.995536 0.980700 0.9974001  0.94976 0.9987063 0.991077  0.89101 0.986847  0.97477   0.89755    0.7636        NA
Prevalence           0.005616 0.024701 0.0035186  0.06440 0.0020614 0.011800  0.14636 0.014572  0.03512   0.15368    0.3973   0.00000
Detection Rate       0.001208 0.005793 0.0009952  0.01628 0.0008175 0.003376  0.04556 0.001955  0.01088   0.06216    0.2288   0.00000
Detection Prevalence 0.012795 0.020294 0.0293929  0.04205 0.0384205 0.055943  0.07517 0.040695  0.03934   0.10673    0.2870   0.02285
Balanced Accuracy    0.601769 0.609832 0.6271651  0.61261 0.6794355 0.616475  0.63832 0.547417  0.64011   0.67591    0.7396        NA
                     Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity                 NA   0.43142  0.372372        NA  0.300000  0.292776        NA        NA  0.331418   0.30604        NA
Specificity           0.991861   0.92430  0.988460  0.990937  0.990038  0.991892  0.992998   0.98333  0.995799   0.96664         1
Pos Pred Value              NA   0.21704  0.438938        NA  0.198847  0.254125        NA        NA  0.598616   0.24813        NA
Neg Pred Value              NA   0.97095  0.984839        NA  0.994206  0.993317        NA        NA  0.987467   0.97482        NA
Prevalence            0.000000   0.04638  0.023671  0.000000  0.008175  0.009347  0.000000   0.00000  0.018553   0.03472         0
Detection Rate        0.000000   0.02001  0.008814  0.000000  0.002452  0.002737  0.000000   0.00000  0.006149   0.01063         0
Detection Prevalence  0.008139   0.09220  0.020081  0.009063  0.012333  0.010769  0.007002   0.01667  0.010272   0.04283         0
Balanced Accuracy           NA   0.67786  0.680416        NA  0.645019  0.642334        NA        NA  0.663608   0.63634        NA
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics

          
test_label    1    2    3    4    5    6    7    8    9   10   11   12   14   15   16   17   18   19   20   22   24   25   31
        1    11    6    0   49    0    1    3    1    0    0    1    0    0    2    8    0   10    4    0    0    3    0    0
        2     4   53    0   76    0   11   28    9    0    9    2    0    0    0    0    0    0    0    0    0    0    0    0
        3     2   42    7   66    0    5   65   13    0   75   17    0    0    0    0    0    0    0    0    0    0    0    0
        4     4   42    0  145    0    6  140    6   37    0    1    0    0    0    0    0    0    0    0    0    0    1    0
        5     1    1    0   65    6    6  120    3   38   10   44    0    0   36    2    0    0    0    0    0    2   43    0
        6     3   23   10   70    0   26  178   16   20  109   65    0    0    0    0    0    0    0    0    0    0    0    0
        7     1   10    1   37    0   13  406   17   65   33   95    0    0    0    0    0    0    0    0    0    0    0    0
        8     1    0    0    1    0    1  145   11   74   57   51    0    0    0    0    0    0    0    0    0    0    2    0
        9     5    8    4   14    0   13  169    8  131   31   22    0    0    0    0    0    0    0    0    0    0    0    0
        10    1    0    6    0    0    6   20   13   13  576  359    0    0    1    0    0    1    0    0    0    0    0    0
        11    0   21    1   28    1    0   27   25    0  368 2148    0    0   41   19    0    0    0    0    0    1   27    0
        12    5   25    0   22    0    7   19    3    0   24   94    0    0    0    1    0    0    0    0    0    0    1    0
        14    0    9    0    4    0    2    3    3    0    2   42    0    0    7    1    0    0    0    0    0    0   17    0
        15    0    0    1    0    5    0    6    2    0   61  505    0    0  202   17    0    1    6    0    0    5   60    0
        16    0    0    0    0    2    0    0    1    0    0   32    0    0   12   70    0   10   12    0    0   19   30    0
        17    0    0    0    0    0    0    0    0    0    0   13    0    0   13    9    0    4    5    0    0    4   36    0
        18    0    0    0    0    0    0    0    0    0    1   20    0    0   19   16    0   17   11    0    0   13    1    0
        19    0    0    0    0    0    0    2    0    0    0    4    0    0    5   19    0   14   32    0    0   53    2    0
        20    0    0    0    0    0    0    1    0    0    0    3    0    0    3    6    0    7   16    0    0   25    8    0
        22    0    0    8    1    2    2    5    0    2   67   36    0    0   12    2    0    0    0    0    0    0   21    0
        24    0    0    0    0    0    0    0    0    0    0    1    0    0    0   13    0    9   20    0    0   61    2    0
        25    0    0    0    0    3    0    2    0    0    4  176    0    0   92   17    0    0    7    0    0    9   82    0
        31    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0

Overall Statistics
                                          
               Accuracy : 0.4248          
                 95% CI : (0.4147, 0.4349)
    No Information Rate : 0.3978          
    P-Value [Acc > NIR] : 5.519e-08       
                                          
                  Kappa : 0.3199          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: 1 Class: 2  Class: 3 Class: 4  Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity          0.289474 0.220833 0.1842105  0.25087 0.3157895 0.262626  0.30321 0.083969  0.34474   0.40364    0.5757        NA
Specificity          0.990579 0.984790 0.9694893  0.97307 0.9603632 0.946767  0.96617 0.964100  0.96955   0.94718    0.9010   0.97857
Pos Pred Value       0.111111 0.276042 0.0239726  0.37958 0.0159151 0.050000  0.59882 0.032070  0.32346   0.57831    0.7935        NA
Neg Pred Value       0.997091 0.979645 0.9965885  0.95187 0.9985559 0.991760  0.89277 0.986720  0.97225   0.89849    0.7627        NA
Prevalence           0.004052 0.025589 0.0040516  0.06163 0.0020258 0.010555  0.14277 0.013967  0.04052   0.15215    0.3978   0.00000
Detection Rate       0.001173 0.005651 0.0007463  0.01546 0.0006397 0.002772  0.04329 0.001173  0.01397   0.06141    0.2290   0.00000
Detection Prevalence 0.010555 0.020471 0.0311334  0.04073 0.0401962 0.055443  0.07229 0.036571  0.04318   0.10619    0.2886   0.02143
Balanced Accuracy    0.640026 0.602812 0.5768499  0.61197 0.6380764 0.604697  0.63469 0.524035  0.65714   0.67541    0.7384        NA
                     Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity                 NA   0.45393  0.350000        NA  0.232877  0.283186        NA        NA  0.312821  0.246246        NA
Specificity           0.990404   0.92512  0.987145  0.991044  0.991296  0.989316  0.992643   0.98315  0.995100  0.965731         1
Pos Pred Value              NA   0.23192  0.372340        NA  0.173469  0.244275        NA        NA  0.575472  0.209184        NA
Neg Pred Value              NA   0.97144  0.985856        NA  0.993966  0.991241        NA        NA  0.985549  0.972071        NA
Prevalence            0.000000   0.04745  0.021324  0.000000  0.007783  0.012048  0.000000   0.00000  0.020791  0.035505         0
Detection Rate        0.000000   0.02154  0.007463  0.000000  0.001813  0.003412  0.000000   0.00000  0.006504  0.008743         0
Detection Prevalence  0.009596   0.09287  0.020045  0.008956  0.010449  0.013967  0.007357   0.01685  0.011302  0.041796         0
Balanced Accuracy           NA   0.68953  0.668572        NA  0.612086  0.636251        NA        NA  0.653960  0.605988        NA
## REDES
crimen <- subset(weapons_violation_tr, select=-c(case_number,block,day,latitude,longitude))

library(kohonen) # for building the SOM map
library(caret)     #for confusion matrix

#Extracting target variable
target_train <- crimen$district
crimen <- subset(crimen, select=-c(district))

crimen$arrest <- as.factor(crimen$arrest)
crimen$arrest <- as.numeric(crimen$arrest)
crimen$primary_type <- as.factor(crimen$primary_type)
crimen$primary_type <- as.numeric(crimen$primary_type)
#narcotics_nn$district <- as.numeric(narcotics_nn$district)
#chicago_crime_nn$district <- as.factor(chicago_crime_nn$district)
crimen$description <- as.factor(crimen$description)
crimen$description <- as.numeric(crimen$description)
crimen$location_description <- as.factor(crimen$location_description)
crimen$location_description <- as.numeric(crimen$location_description)
crimen$month <- as.numeric(crimen$month)

#Scaling original data
set.seed(7)
#target_train.sc<-scale(chicago_crime_nn_tr)
#target_test.sc<-scale(chicago_crime_nn)

# creation of training and test datasets
index <- sample(nrow(crimen), round(0.75*nrow(crimen)))
train <- crimen[index,]
test <- crimen[-index,]

#train <- chicago_crime_nn_tr
train <- as.matrix(train)
#test <- chicago_crime_nn
test <- as.matrix(test)

#train_label<-target_train
#test_label<-target_test
train_label<-target_train[index]
test_label<-target_train[-index]

#main characteristics of the map
som_grid<-somgrid(xdim=12, ydim=12, topo="hexagonal")

#training the map
crime.som <- som(train, grid=som_grid, 
               rlen=100, alpha=c(0.05, 0.01), 
               radius= 2, keep.data=T)

# Names of the variables used
colnames(train)
[1] "primary_type"         "description"          "location_description" "arrest"               "ward"                
[6] "month"               
# main characteristics of the map
summary(crime.som)
SOM of size 12x12 with a hexagonal topology and a bubble neighbourhood function.
The number of data layers is 1.
Distance measure(s) used: sumofsquares.
Training data included: 10154 objects.
Mean distance to the closest unit in the map: 7.334.
#Showing the training process
plot(crime.som, type="changes")


#node counts
plot(crime.som, type="counts", main="Examples per Neuron")


#Codes/Weight vectors
plot(crime.som, type="codes", main="Patterns Discovered")


#Scaling original data
set.seed(7)

#main characteristics of the map
som_grid<-somgrid(xdim=12, ydim=12, topo="hexagonal")
set.seed(7)
kohmap <- xyf(train, train_label,
              grid=som_grid, 
              rlen=100, alpha=c(0.05, 0.01), 
              radius= 2, keep.data=T)

#Showing the training process
plot(kohmap, type="changes")


#Showing distribution of wine labels in neurons
plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c("Crime"))


plot(kohmap, type="codes",  codeRendering = "lines", shape="straight",
     main=c(" patterns"))


# Plotting classes in neurons
#plot(kohmap, type="mapping", labels=as.numeric(train_label)+3,
#     col=as.numeric(train_label)+3, pch=4, main="Map of classes", palette.name = terrain.colors)

#Prediction using the training data
print("TRAINING PREDICTION")
[1] "TRAINING PREDICTION"
kohmap.predict_tr<- predict(kohmap, newdata=train, whatmap = 1)
prediction_table_tr<-table(train_label,kohmap.predict_tr$predictions[[2]])
confusionMatrix(prediction_table_tr)
Confusion Matrix and Statistics

           
train_label   1   2   3   4   5   6   7   8   9  10  11  12  14  15  16  17  18  19  20  22  24  25  31
         1    7  28   8   7   3   4   0   0   0   1   1   4   1   0   2   1   1   5   0   0   0   0   0
         2    4 141  66  26   1  38  10   0   0   3   0   0   1   0   0   0   0   0   0   0   0   0   0
         3    1  48 178 103   7 152  27   0   0   7   0   0   0   0   0   0   0   0   0   0   0   0   0
         4    0  29  34 496 104  55   9   0  22   0   0   0   0   0   0   0   0   0   0   0   0   0   0
         5    0   3   2 262 462  15  12   0  11   0   0   0   0   7   0   3   1   0   0   0   0  43   0
         6    0  23  81 166  30 285 303   0   2  44   2   0   0   0   0   0   0   0   0   0   0   0   0
         7    0  28  51  55   1 100 883  25   0   2   0   0   0   0   0   0   0   0   0   0   0   0   0
         8    0   0  24   2   1  13 302  43  42  52   1   0   0   0   0   0   0   0   0   0   0   0   0
         9    7  38  39  51  18  42 233  15 118   8   3   0   0   0   0   0   0   0   0   0   0   0   0
         10   0   0   0   9   5  41  15   0  58 675  69   0   0   9   0   0   0   0   0   0   0   3   0
         11   0  38   5   4  13   5   2   0   0 336 560   2   4 134   0   0   5   0   0   0   0  53   0
         12   7  37  10   6   0   1   0   0   0  74  68   5   3   3   0   1   2   0   0   0   0   3   0
         14   2  14   3   1  28   2   0   0   0  26  43   2   9  10   0   1   1   0   0   0   0  20   0
         15   0   0   0   0  66   1   0   0   0  39 257   0   0 183   0   2   2   1   0   0   0  88   0
         16   0   0   0   0  24   0   0   0   0   0   3   0   0   4  13   1   5  22   0   0   7  21   0
         17   0   0   0   0  49   0   0   0   0   0  13   0   0   9   2  15   1   3   0   0   4  29   0
         18   0   4   0   0   2   0   0   0   0   4  29   0   0   3   4   8  10  19   0   0   0   9   0
         19   1   1   0   0   3   0   0   0   0   0   5   0   0   0   1   0   3  45   0   0  32   2   0
         20   0   0   0   0   8   0   0   0   0   0   0   0   0   2   5   3   2  14   0   0  32   9   0
         22   0   0  26  10 104  90  20   0   1  30   4   0   0   7   0   2   0   0   0   0   0  14   0
         24   0   0   0   0   3   0   0   0   0   0   1   0   0   2   3   2   1  11   0   0 106  10   0
         25   0   2   0   0 120   1   0   0   0  10 156   0   0  83   0   4   0   1   0   0   0 190   0
         31   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

Overall Statistics
                                         
               Accuracy : 0.4357         
                 95% CI : (0.426, 0.4454)
    No Information Rate : 0.1788         
    P-Value [Acc > NIR] : < 2.2e-16      
                                         
                  Kappa : 0.3855         
                                         
 Mcnemar's Test P-Value : NA             

Statistics by Class:

                      Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity          0.2413793  0.32488  0.33776  0.41402  0.43916  0.33728  0.48623 0.518072  0.46457   0.51487   0.46091 0.3846154
Specificity          0.9934815  0.98467  0.96416  0.97175  0.96056  0.93007  0.96858 0.956608  0.95414   0.97637   0.93277 0.9787989
Pos Pred Value       0.0958904  0.48621  0.34034  0.66222  0.56273  0.30449  0.77118 0.089583  0.20629   0.76357   0.48234 0.0227273
Neg Pred Value       0.9978177  0.97030  0.96376  0.92536  0.93678  0.93925  0.89644 0.995865  0.98581   0.93139   0.92717 0.9991947
Prevalence           0.0028560  0.04274  0.05190  0.11798  0.10360  0.08322  0.17885 0.008174  0.02501   0.12911   0.11966 0.0012803
Detection Rate       0.0006894  0.01389  0.01753  0.04885  0.04550  0.02807  0.08696 0.004235  0.01162   0.06648   0.05515 0.0004924
Detection Prevalence 0.0071893  0.02856  0.05151  0.07376  0.08085  0.09218  0.11276 0.047272  0.05633   0.08706   0.11434 0.0216663
Balanced Accuracy    0.6174304  0.65478  0.65096  0.69289  0.69986  0.63367  0.72741 0.737340  0.70935   0.74562   0.69684 0.6817072
                     Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity          0.5000000   0.40132  0.433333  0.348837 0.2941176  0.371901        NA        NA   0.58564   0.38462        NA
Specificity          0.9849053   0.95298  0.991407  0.989121 0.9918972  0.995216  0.992614   0.96967   0.99669   0.96097         1
Pos Pred Value       0.0555556   0.28638  0.130000  0.120000 0.1086957  0.483871        NA        NA   0.76259   0.33510        NA
Neg Pred Value       0.9990993   0.97131  0.998309  0.997208 0.9976148  0.992446        NA        NA   0.99251   0.96829        NA
Prevalence           0.0017727   0.04491  0.002955  0.004235 0.0033484  0.011916  0.000000   0.00000   0.01783   0.04865         0
Detection Rate       0.0008864   0.01802  0.001280  0.001477 0.0009848  0.004432  0.000000   0.00000   0.01044   0.01871         0
Detection Prevalence 0.0159543   0.06293  0.009848  0.012310 0.0090605  0.009159  0.007386   0.03033   0.01369   0.05584         0
Balanced Accuracy    0.7424526   0.67715  0.712370  0.668979 0.6430074  0.683558        NA        NA   0.79116   0.67279        NA
#Prediction using the test data
print("TEST PREDICTION")
[1] "TEST PREDICTION"
kohmap.predict<- predict(kohmap, newdata=test, whatmap = 1)
prediction_table<-table(test_label,kohmap.predict$predictions[[2]])
confusionMatrix(prediction_table)
Confusion Matrix and Statistics

          
test_label   1   2   3   4   5   6   7   8   9  10  11  12  14  15  16  17  18  19  20  22  24  25  31
        1    2  14   1   4   0   0   0   0   0   0   1   0   1   0   0   3   0   5   0   0   0   2   0
        2    1  38  19   9   1  14   4   0   0   1   0   1   3   0   0   0   0   0   0   0   0   0   0
        3    0  19  46  25   4  47  13   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        4    0  12   7 174  35  23   8   0   7   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        5    0   1   2  89 131  11   3   0   6   0   2   0   0   2   0   1   0   0   0   0   0  16   0
        6    0   8  31  61   9 103 102   0   1  18   0   0   0   0   0   0   0   0   0   0   0   0   0
        7    0  13  20  27   1  43 324  11   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        8    0   0  12   0   2   3  98  20  18  14   0   0   0   0   0   0   0   0   0   0   0   0   0
        9    4  18  12  14  12  14  65   3  26   1   2   0   0   0   0   0   0   0   0   0   0   0   0
        10   0   0   0   2   4  20   7   0  17 188  32   0   0   5   0   0   0   0   0   0   0   0   0
        11   1   8   3   0   5   7   1   0   0 106 179   0   1  48   0   1   1   0   0   0   0  13   0
        12   5  14   3   3   0   1   0   0   0  22  21   1   2   1   0   0   1   0   0   0   0   3   0
        14   0   9   3   0   6   1   0   0   0   8  19   2   1   0   0   1   0   0   0   0   0   4   0
        15   0   0   0   0  16   1   0   0   0  15  84   0   0  55   0   1   0   1   0   0   0  32   0
        16   0   0   0   0   6   0   0   0   0   0   2   0   0   3   4   1   1   7   0   0   2   6   0
        17   0   0   0   0  22   0   0   0   0   0   3   0   0   4   1   3   0   1   0   0   0  16   0
        18   0   1   0   0   0   0   0   0   0   0  10   0   0   0   1   4   5   6   0   0   0   3   0
        19   0   1   0   0   2   0   0   0   0   0   0   0   0   0   0   0   0  14   0   0  12   1   0
        20   0   0   0   0   3   0   0   0   0   0   0   0   0   1   3   3   0   3   0   0   7   1   0
        22   0   0   7   2  30  28   4   0   1  17   0   0   0   1   0   0   0   0   0   0   0   3   0
        24   0   0   0   0   2   0   0   0   0   0   0   0   0   1   2   0   1   7   0   0  21   4   0
        25   0   0   0   0  33   0   0   0   0   4  39   0   0  38   0   0   0   0   0   0   0  73   0
        31   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

Overall Statistics
                                          
               Accuracy : 0.4161          
                 95% CI : (0.3994, 0.4329)
    No Information Rate : 0.1859          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.3626          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: 1 Class: 2 Class: 3 Class: 4 Class: 5 Class: 6 Class: 7 Class: 8 Class: 9 Class: 10 Class: 11 Class: 12
Sensitivity          0.153846  0.24359  0.27711  0.42439  0.40432  0.32595  0.51510  0.58824 0.342105   0.47716    0.4543 0.2500000
Specificity          0.990804  0.98358  0.96644  0.96907  0.95654  0.92503  0.95826  0.95612 0.956167   0.97090    0.9348 0.9775148
Pos Pred Value       0.060606  0.41758  0.29870  0.65414  0.49621  0.30931  0.73804  0.11976 0.152047   0.68364    0.4786 0.0129870
Neg Pred Value       0.996717  0.96417  0.96285  0.92431  0.93814  0.93019  0.89643  0.99565 0.984438   0.93374    0.9286 0.9990928
Prevalence           0.003842  0.04610  0.04905  0.12116  0.09574  0.09338  0.18587  0.01005 0.022459   0.11643    0.1164 0.0011820
Detection Rate       0.000591  0.01123  0.01359  0.05142  0.03871  0.03044  0.09574  0.00591 0.007683   0.05556    0.0529 0.0002955
Detection Prevalence 0.009752  0.02689  0.04551  0.07861  0.07801  0.09840  0.12973  0.04935 0.050532   0.08126    0.1105 0.0227541
Balanced Accuracy    0.572325  0.61359  0.62177  0.69673  0.68043  0.62549  0.73668  0.77218 0.649136   0.72403    0.6945 0.6137574
                     Class: 14 Class: 15 Class: 16 Class: 17 Class: 18 Class: 19 Class: 20 Class: 22 Class: 24 Class: 25 Class: 31
Sensitivity          0.1250000   0.34591  0.363636 0.1666667  0.555556  0.318182        NA        NA  0.500000   0.41243        NA
Specificity          0.9843009   0.95349  0.991699 0.9860368  0.992593  0.995210  0.993794   0.97252  0.994913   0.96445         1
Pos Pred Value       0.0185185   0.26829  0.125000 0.0600000  0.166667  0.466667        NA        NA  0.552632   0.39037        NA
Neg Pred Value       0.9978979   0.96729  0.997912 0.9955009  0.998807  0.991055        NA        NA  0.993724   0.96747        NA
Prevalence           0.0023641   0.04699  0.003251 0.0053191  0.002660  0.013002  0.000000   0.00000  0.012411   0.05230         0
Detection Rate       0.0002955   0.01625  0.001182 0.0008865  0.001478  0.004137  0.000000   0.00000  0.006206   0.02157         0
Detection Prevalence 0.0159574   0.06058  0.009456 0.0147754  0.008865  0.008865  0.006206   0.02748  0.011229   0.05526         0
Balanced Accuracy    0.5546505   0.64970  0.677668 0.5763518  0.774074  0.656696        NA        NA  0.747457   0.68844        NA
library(RColorBrewer)
groups<-23
#Applying hierarchical clustering for grouping patterns
crime.hc=cutree(hclust(dist(crime.som$codes[[1]])), groups)
plot(crime.som, type="codes", bgcol = heat.colors(groups)[crime.hc],
     main="clustering the patterns discovered")
add.cluster.boundaries(crime.som,crime.hc)

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgUkVBRCBUSEUgREFUQQoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShtbHRvb2xzKQpjaGljYWdvX2NyaW1lIDwtIHJlYWQudGFibGUoZmlsZSA9ICJjaGljYWdvX2NyaW1lX2NsZWFuLmNzdiIsICNOYW1lIG9mIHRleHQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwgICAgICAgICAgICAgICAgICAgICAgICNTZXBhcmF0aW9uIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsICAgICAgICAgICAgICAgICAgICNJZiBjb2x1bW4gbmFtZXMgYXJlIGluIHRoZSBmaXJzdCByb3cuCiAgICAgICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gIk5BIiwgICAgICAgICAgICAgICAjQ2hhcmFjdGVyIHRvIGJlIG1hcmtlZCBhcyBtaXNzaW5nIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSAoZ3N1YigiLCIsIiAiLGNoaWNhZ29fY3JpbWUkbG9jYXRpb25fZGVzY3JpcHRpb24pKQpjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjo9IiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjoiLCIiLGNoaWNhZ29fY3JpbWUkZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWUkZGVzY3JpcHRpb24gPC0gZ3N1YigiTUFOVS9QT1NTLiBXLyIsIiIsY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIihFLkcuICBVQkVSICBMWUZUKSIsIiIsY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQoKY2hpY2Fnb19jcmltZSA8LSBjaGljYWdvX2NyaW1lICU+JQogICAgZHBseXI6Om11dGF0ZSh5ZWFyID0gbHVicmlkYXRlOjp5ZWFyKGRhdGUpLCAKICAgICAgICAgICAgICAgIG1vbnRoID0gbHVicmlkYXRlOjptb250aChkYXRlKSwgCiAgICAgICAgICAgICAgICBkYXkgPSBsdWJyaWRhdGU6OmRheShkYXRlKSkKY2hpY2Fnb19jcmltZSA8LSBuYS5vbWl0KGNoaWNhZ29fY3JpbWUpCmNoaWNhZ29fY3JpbWUgPC0gc2VsZWN0KGNoaWNhZ29fY3JpbWUsLWMoWCx1bmlxdWVfa2V5LCB4X2Nvb3JkaW5hdGUsIHlfY29vcmRpbmF0ZSwgbG9jYXRpb24sIGRvbWVzdGljLCBmYmlfY29kZSwgZGF0ZSx5ZWFyKSkKY2hpY2Fnb19jcmltZSRkaXN0cmljdCA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZSRkaXN0cmljdCkKCnVuaXF1ZShjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSkKCmhlYWQoY2hpY2Fnb19jcmltZSkKc3VtbWFyeShjaGljYWdvX2NyaW1lKQpgYGAKCiMjIFJlYWQgdGhlIHRyYWluaW5nIHNldAoKYGBge3J9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShtbHRvb2xzKQpjaGljYWdvX2NyaW1lX3RyIDwtIHJlYWQudGFibGUoZmlsZSA9ICJjaGljYWdvX2NyaW1lX3RyLmNzdiIsICNOYW1lIG9mIHRleHQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwgICAgICAgICAgICAgICAgICAgICAgICNTZXBhcmF0aW9uIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsICAgICAgICAgICAgICAgICAgICNJZiBjb2x1bW4gbmFtZXMgYXJlIGluIHRoZSBmaXJzdCByb3cuCiAgICAgICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gIk5BIiwgICAgICAgICAgICAgICAjQ2hhcmFjdGVyIHRvIGJlIG1hcmtlZCBhcyBtaXNzaW5nIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKY2hpY2Fnb19jcmltZV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSAoZ3N1YigiLCIsIiAiLGNoaWNhZ29fY3JpbWVfdHIkbG9jYXRpb25fZGVzY3JpcHRpb24pKQpjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjo9IiwiIixjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uIDwtIGdzdWIoIjoiLCIiLGNoaWNhZ29fY3JpbWVfdHIkZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfdHIkZGVzY3JpcHRpb24gPC0gZ3N1YigiTUFOVS9QT1NTLiBXLyIsIiIsY2hpY2Fnb19jcmltZV90ciRkZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZV90ciRkZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lX3RyJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRkZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIihFLkcuICBVQkVSICBMWUZUKSIsIiIsY2hpY2Fnb19jcmltZV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIsIiwiIixjaGljYWdvX2NyaW1lX3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCIuIiwiIixjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQoKY2hpY2Fnb19jcmltZV90ciA8LSBjaGljYWdvX2NyaW1lX3RyICU+JQogICAgZHBseXI6Om11dGF0ZSh5ZWFyID0gbHVicmlkYXRlOjp5ZWFyKGRhdGUpLCAKICAgICAgICAgICAgICAgIG1vbnRoID0gbHVicmlkYXRlOjptb250aChkYXRlKSwgCiAgICAgICAgICAgICAgICBkYXkgPSBsdWJyaWRhdGU6OmRheShkYXRlKSkKCmNoaWNhZ29fY3JpbWVfdHIgPC0gc2VsZWN0KGNoaWNhZ29fY3JpbWVfdHIsLWMoWCx1bmlxdWVfa2V5LCB4X2Nvb3JkaW5hdGUsIHlfY29vcmRpbmF0ZSwgbG9jYXRpb24sIGRvbWVzdGljLCBmYmlfY29kZSwgZGF0ZSx5ZWFyKSkKCmNoaWNhZ29fY3JpbWVfdHIgPC0gbmEub21pdChjaGljYWdvX2NyaW1lX3RyKQpjaGljYWdvX2NyaW1lX3RyJGRpc3RyaWN0IDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX3RyJGRpc3RyaWN0KQoKdW5pcXVlKGNoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlKQoKaGVhZChjaGljYWdvX2NyaW1lX3RyKQpzdW1tYXJ5KGNoaWNhZ29fY3JpbWVfdHIpCgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA9PSAiQ1JJTUlOQUwgVFJFU1BBU1MiXSA8LSAiUk9CQkVSWSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIkJVUkdMQVJZIl0gPC0gIlJPQkJFUlkiCmNoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlID09ICJNT1RPUiBWRUhJQ0xFIFRIRUZUIl0gPC0gIlRIRUZUIgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA9PSAiSE9NSUNJREUiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIktJRE5BUFBJTkciXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIkJBVFRFUlkiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIklOVElNSURBVElPTiJdIDwtICJWSU9MRU5UIENSSU1FIgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA9PSAiQVJTT04iXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIlBST1NUSVRVVElPTiJdIDwtICJTRVggT0ZGRU5TRSIKY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUgPT0gIkNSSU0gU0VYVUFMIEFTU0FVTFQiXSA8LSAiU0VYIE9GRkVOU0UiCmNoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHIkcHJpbWFyeV90eXBlID09ICJPVEhFUiBOQVJDT1RJQyBWSU9MQVRJT04iXSA8LSAiTkFSQ09USUNTIgpjaGljYWdvX2NyaW1lX3RyJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZV90ciRwcmltYXJ5X3R5cGUpCgpjaGljYWdvX2NyaW1lX3N1YnNldF90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV90ciwgcHJpbWFyeV90eXBlPT0iQVNTQVVMVCIgfCBwcmltYXJ5X3R5cGUgPT0gIlZJT0xFTlQgQ1JJTUUiIHwgcHJpbWFyeV90eXBlID09ICJUSEVGVCIgfCBwcmltYXJ5X3R5cGU9PSJOQVJDT1RJQ1MiIHwgcHJpbWFyeV90eXBlID09ICJXRUFQT05TIFZJT0xBVElPTiIgfCBwcmltYXJ5X3R5cGU9PSJST0JCRVJZIiB8IHByaW1hcnlfdHlwZSA9PSAiQ1JJTUlOQUwgREFNQUdFIiB8IHByaW1hcnlfdHlwZSA9PSAiREVDRVBUSVZFIFBSQUNUSUNFIiApCgpjaGljYWdvX2NyaW1lX3N1YnNldF90ciRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyJHByaW1hcnlfdHlwZSkKY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIgPC0gbmEub21pdChjaGljYWdvX2NyaW1lX3N1YnNldF90cikKbGlicmFyeShEYXRhRXhwbG9yZXIpCnBsb3Rfc3RyKGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyKQpwbG90X21pc3NpbmcoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIpCiNwbG90X2hpc3RvZ3JhbShjaGljYWdvX2NyaW1lX3N1YnNldCkKI3Bsb3RfZGVuc2l0eShjaGljYWdvX2NyaW1lX3N1YnNldCkKI3Bsb3RfY29ycmVsYXRpb24oY2hpY2Fnb19udW1lcmljLCB0eXBlID0gJ2NvbnRpbnVvdXMnKQpjaGljYWdvX2NyaW1lX3N1YnNldF90ciRtb250aCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIkbW9udGgpCgpwbG90X2JhcihjaGljYWdvX2NyaW1lX3N1YnNldF90cikKYGBgCiMjIEVYUExPUkFUT1JZIEFOQUxZU0lTCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCgpnZ3Bsb3QoZGF0YSA9IGNoaWNhZ29fY3JpbWUpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBwcmltYXJ5X3R5cGUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmNoaWNhZ29fY3JpbWUgJT4lIAogIGNvdW50KHByaW1hcnlfdHlwZSkKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpCgpjaGljYWdvX2NyaW1lICU+JSAKICBjb3VudChkaXN0cmljdCkKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGFycmVzdCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpKQoKY2hpY2Fnb19jcmltZSAlPiUgCiAgY291bnQoYXJyZXN0KQoKI2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlIDwtIGFzLmNoYXJhY3RlcihqdW5rJG5tKQpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA9PSAiQ1JJTUlOQUwgVFJFU1BBU1MiXSA8LSAiUk9CQkVSWSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIkJVUkdMQVJZIl0gPC0gIlJPQkJFUlkiCmNoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlID09ICJNT1RPUiBWRUhJQ0xFIFRIRUZUIl0gPC0gIlRIRUZUIgpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA9PSAiSE9NSUNJREUiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIktJRE5BUFBJTkciXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIkJBVFRFUlkiXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIklOVElNSURBVElPTiJdIDwtICJWSU9MRU5UIENSSU1FIgpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA9PSAiQVJTT04iXSA8LSAiVklPTEVOVCBDUklNRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIlBST1NUSVRVVElPTiJdIDwtICJTRVggT0ZGRU5TRSIKY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPT0gIkNSSU0gU0VYVUFMIEFTU0FVTFQiXSA8LSAiU0VYIE9GRkVOU0UiCmNoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlID09ICJPVEhFUiBOQVJDT1RJQyBWSU9MQVRJT04iXSA8LSAiTkFSQ09USUNTIgpjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUpCgpnZ3Bsb3QoZGF0YSA9IGNoaWNhZ29fY3JpbWUpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBwcmltYXJ5X3R5cGUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmNoaWNhZ29fY3JpbWUgJT4lIAogIGNvdW50KHByaW1hcnlfdHlwZSkKCmNoaWNhZ29fY3JpbWVfc3Vic2V0IDwtIHN1YnNldChjaGljYWdvX2NyaW1lLCBwcmltYXJ5X3R5cGU9PSJBU1NBVUxUIiB8IHByaW1hcnlfdHlwZSA9PSAiVklPTEVOVCBDUklNRSIgfCBwcmltYXJ5X3R5cGUgPT0gIlRIRUZUIiB8IHByaW1hcnlfdHlwZT09Ik5BUkNPVElDUyIgfCBwcmltYXJ5X3R5cGUgPT0gIldFQVBPTlMgVklPTEFUSU9OIiB8IHByaW1hcnlfdHlwZT09IlJPQkJFUlkiIHwgcHJpbWFyeV90eXBlID09ICJDUklNSU5BTCBEQU1BR0UiIHwgcHJpbWFyeV90eXBlID09ICJERUNFUFRJVkUgUFJBQ1RJQ0UiICkKY2hpY2Fnb19jcmltZV9zdWJzZXQkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX3N1YnNldCRwcmltYXJ5X3R5cGUpCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZV9zdWJzZXQpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBwcmltYXJ5X3R5cGUpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZV9zdWJzZXQpICsKICBnZW9tX2NvdW50KG1hcHBpbmcgPSBhZXMoeCA9IHByaW1hcnlfdHlwZSwgeSA9IGRpc3RyaWN0KSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQoKZ2dwbG90KGRhdGEgPSBjaGljYWdvX2NyaW1lX3N1YnNldCkgKwogIGdlb21fY291bnQobWFwcGluZyA9IGFlcyh4ID0gYXJyZXN0LCB5ID0gcHJpbWFyeV90eXBlKSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQoKZ2dwbG90KGRhdGEgPSBjaGljYWdvX2NyaW1lX3N1YnNldCkgKwogIGdlb21fY291bnQobWFwcGluZyA9IGFlcyh4ID0gYXJyZXN0LCB5ID0gZGlzdHJpY3QpKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpCgpgYGAKCiMjIEVYUExPUkFUT1JZIEFOQUxZU0lTIEJZIENSSU1FCgpgYGB7cn0KYXNzYXVsdCA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHByaW1hcnlfdHlwZT09IkFTU0FVTFQiKQp2aW9sZW50X2NyaW1lIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgcHJpbWFyeV90eXBlPT0iVklPTEVOVCBDUklNRSIpCnRoZWZ0IDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgcHJpbWFyeV90eXBlPT0iVEhFRlQiKQpuYXJjb3RpY3MgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBwcmltYXJ5X3R5cGU9PSJOQVJDT1RJQ1MiKQp3ZWFwb25zX3Zpb2xhdGlvbiA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHByaW1hcnlfdHlwZT09IldFQVBPTlMgVklPTEFUSU9OIikKcm9iYmVyeSA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHByaW1hcnlfdHlwZT09IlJPQkJFUlkiKQpjcmltaW5hbF9kYW1hZ2UgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBwcmltYXJ5X3R5cGU9PSJDUklNSU5BTCBEQU1BR0UiKQpkZWNlcHRpdmVfcHJhY3RpY2UgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBwcmltYXJ5X3R5cGU9PSJERUNFUFRJVkUgUFJBQ1RJQ0UiKQoKYXNzYXVsdF90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHByaW1hcnlfdHlwZT09IkFTU0FVTFQiKQp2aW9sZW50X3RyX2NyaW1lIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF90ciwgcHJpbWFyeV90eXBlPT0iVklPTEVOVCBDUklNRSIpCnRoZWZ0X3RyIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF90ciwgcHJpbWFyeV90eXBlPT0iVEhFRlQiKQpuYXJjb3RpY3NfdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBwcmltYXJ5X3R5cGU9PSJOQVJDT1RJQ1MiKQp3ZWFwb25zX3Zpb2xhdGlvbl90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHByaW1hcnlfdHlwZT09IldFQVBPTlMgVklPTEFUSU9OIikKcm9iYmVyeV90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHByaW1hcnlfdHlwZT09IlJPQkJFUlkiKQpjcmltaW5hbF9kYW1hZ2VfdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBwcmltYXJ5X3R5cGU9PSJDUklNSU5BTCBEQU1BR0UiKQpkZWNlcHRpdmVfcHJhY3RpY2VfdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBwcmltYXJ5X3R5cGU9PSJERUNFUFRJVkUgUFJBQ1RJQ0UiKQpgYGAKCiMjIERJU1RSSUNUUwoKYGBge3J9CmxpYnJhcnkoc3FsZGYpCgpkaXN0cmljdHNfdHJ1ZSA8LSBzcWxkZignU0VMRUNUIGRpc3RyaWN0LCBBVkcobGF0aXR1ZGUpIGFzIGF2Z19sYXRpdHVkZSxBVkcobG9uZ2l0dWRlKSBhcyBhdmdfbG9uZ2l0dWRlLCBjb3VudCgqKSBhcyBhcnJlc3QgRlJPTSBjaGljYWdvX2NyaW1lX3N1YnNldCBXSEVSRSBhcnJlc3QgTElLRSAiVHJ1ZSIgR1JPVVAgQlkgZGlzdHJpY3QgT1JERVIgQlkgZGlzdHJpY3QnKQpkaXN0cmljdHNfZmFsc2UgPC0gc3FsZGYoJ1NFTEVDVCBkaXN0cmljdCwgQVZHKGxhdGl0dWRlKSBhcyBhdmdfbGF0aXR1ZGUsQVZHKGxvbmdpdHVkZSkgYXMgYXZnX2xvbmdpdHVkZSwgY291bnQoKikgYXMgbm9fYXJyZXN0IEZST00gY2hpY2Fnb19jcmltZV9zdWJzZXQgV0hFUkUgYXJyZXN0IExJS0UgIkZhbHNlIiBHUk9VUCBCWSBkaXN0cmljdCBPUkRFUiBCWSBkaXN0cmljdCcpCmRpc3RyaWN0c190cnVlJGFycmVzdCA8LSBhcy5udW1lcmljKGRpc3RyaWN0c190cnVlJGFycmVzdCkKZGlzdHJpY3RzX2ZhbHNlJG5vX2FycmVzdCA8LSBhcy5udW1lcmljKGRpc3RyaWN0c19mYWxzZSRub19hcnJlc3QpCmRpc3RyaWN0c190cnVlCmRpc3RyaWN0c19mYWxzZQoKcG9saWNlX2Rpc3RyaWN0cyA8LSByZWFkLnRhYmxlKGZpbGUgPSAiUG9saWNlX1N0YXRpb25zLmNzdiIsICNOYW1lIG9mIHRleHQgZmlsZS4KICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIsIiwgICAgICAgICAgICAgICAgICAgICAgICNTZXBhcmF0aW9uIGNoYXJhY3Rlci4KICAgICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IFRSVUUsICAgICAgICAgICAgICAgICAgICNJZiBjb2x1bW4gbmFtZXMgYXJlIGluIHRoZSBmaXJzdCByb3cuCiAgICAgICAgICAgICAgICAgICAgICBuYS5zdHJpbmdzID0gIk5BIiwgICAgICAgICAgICAgICAjQ2hhcmFjdGVyIHRvIGJlIG1hcmtlZCBhcyBtaXNzaW5nIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpwb2xpY2VfZGlzdHJpY3RzCgpwb2xpY2VfZGlzdHJpY3RzJERJU1RSSUNUW3BvbGljZV9kaXN0cmljdHMkRElTVFJJQ1QgPT0gIkhlYWRxdWFydGVycyJdIDwtICIwIgpwb2xpY2VfZGlzdHJpY3RzJERJU1RSSUNUIDwtIGFzLmZhY3Rvcihwb2xpY2VfZGlzdHJpY3RzJERJU1RSSUNUKQoKZGlzdHJpY3RzIDwtIHNxbGRmKCdTRUxFQ1QgRElTVFJJQ1QgYXMgZGlzdHJpY3QsIExBVElUVURFIGFzIGxhdGl0dWRlLExPTkdJVFVERSBhcyBsb25naXR1ZGUgRlJPTSBwb2xpY2VfZGlzdHJpY3RzJykKCmFycmVzdF9wZXJjZW50YWdlIDwtIGRhdGEuZnJhbWUoJ0Rpc3RyaWN0JyA9IGRpc3RyaWN0c19mYWxzZSRkaXN0cmljdCwgJ1BjdEFycmVzdCcgPSBkaXN0cmljdHNfdHJ1ZSRhcnJlc3QvKGRpc3RyaWN0c190cnVlJGFycmVzdCArIGRpc3RyaWN0c19mYWxzZSRub19hcnJlc3QpLCAnQ3JpbWVzJyA9IChkaXN0cmljdHNfdHJ1ZSRhcnJlc3QgKyBkaXN0cmljdHNfZmFsc2Ukbm9fYXJyZXN0KSkKYXJyZXN0X3BlcmNlbnRhZ2UKCmdncGxvdChkYXRhID0gYXJyZXN0X3BlcmNlbnRhZ2UpICsKICBnZW9tX2NvbChtYXBwaW5nID0gYWVzKHggPSBEaXN0cmljdCwgeSA9IENyaW1lcykpICsKICBnZW9tX2xpbmUoYWVzKHggPSBEaXN0cmljdCwgeSA9IFBjdEFycmVzdCoxMDAwMCwgZ3JvdXAgPSAxKSwgY29sb3IgPSAieWVsbG93IikgKwogIHNjYWxlX3lfY29udGludW91cyhzZWMuYXhpcyA9IHNlY19heGlzKH4uLzEwMDAwLCBuYW1lID0gIlBjdEFycmVzdCIpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSkKCiMjIElOSVRJQUxJWkUKbGlicmFyeSgibGVhZmxldCIpCmxpYnJhcnkoImRhdGEudGFibGUiKQpsaWJyYXJ5KCJzcCIpCmxpYnJhcnkoInJnZGFsIikKIyBsaWJyYXJ5KCJtYXB0b29scyIpCmxpYnJhcnkoIktlcm5TbW9vdGgiKQoKc2V0RFQoZGlzdHJpY3RzX2ZhbHNlKQoKI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1YigiZGthaGxlL2dnbWFwIiwgcmVmID0gInRpZHl1cCIsIGZvcmNlID0gVFJVRSkKbGlicmFyeShnZ21hcCkKY2hpY2FnbyA8LSBnZXRfc3RhbWVubWFwKGJib3ggPSBjKGxlZnQgPSAtODguMDIyNSwgYm90dG9tID0gNDEuNTk0OSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWdodCA9IC04Ny4yNzEzLCB0b3AgPSA0Mi4wNjc3KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICB6b29tID0gMTEpCmdnbWFwKGNoaWNhZ28pICsKZ2VvbV90ZXh0KGFlcyh4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsIGxhYmVsID0gZGlzdHJpY3QpLCBkYXRhID0gZGlzdHJpY3RzKQpgYGAKCgpgYGB7cn0KCmxpYnJhcnkoZ2dtYXApCmNoaWNhZ28gPC0gZ2V0X3N0YW1lbm1hcChiYm94ID0gYyhsZWZ0ID0gLTg4LjAyMjUsIGJvdHRvbSA9IDQxLjU5NDksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSAtODcuMjcxMywgdG9wID0gNDIuMDY3NyksIAogICAgICAgICAgICAgICAgICAgICAgICAgem9vbSA9IDExKQpnZ21hcChjaGljYWdvKSArCmdlb21fdGV4dChhZXMoeCA9IExPTkdJVFVERSwgeSA9IExBVElUVURFLCBsYWJlbCA9IERJU1RSSUNUKSwgZGF0YSA9IHBvbGljZV9kaXN0cmljdHMpCmBgYAoKYGBge3J9CmdncGxvdChkYXRhID0gYXNzYXVsdCkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJBU1NBVUxUIEJZIERJU1RSSUNUIikKCmdncGxvdChkYXRhID0gdGhlZnQpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBkaXN0cmljdCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDEpKSArCiAgZ2d0aXRsZSgiVEhFRlRTIEJZIERJU1RSSUNUIikKCmdncGxvdChkYXRhID0gdmlvbGVudF9jcmltZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJWSU9MRU5UIENSSU1FUyBCWSBESVNUUklDVCIpCgpnZ3Bsb3QoZGF0YSA9IG5hcmNvdGljcykgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJOQVJDT1RJQyBDUklNRVMgQlkgRElTVFJJQ1QiKQoKZ2dwbG90KGRhdGEgPSB3ZWFwb25zX3Zpb2xhdGlvbikgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJXRUFQT04tUkVMQVRFRCBDUklNRVMgQlkgRElTVFJJQ1QiKQoKZ2dwbG90KGRhdGEgPSByb2JiZXJ5KSArCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gZGlzdHJpY3QpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSkgKwogIGdndGl0bGUoIlJPQkJFUklFUyBCWSBESVNUUklDVCIpCgpnZ3Bsb3QoZGF0YSA9IGNyaW1pbmFsX2RhbWFnZSkgKwogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3RyaWN0KSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMSkpICsKICBnZ3RpdGxlKCJDUklNSU5BTCBEQU1BR0UgQ1JJTUVTIEJZIERJU1RSSUNUIikKCmdncGxvdChkYXRhID0gZGVjZXB0aXZlX3ByYWN0aWNlKSArCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gZGlzdHJpY3QpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoaGp1c3QgPSAxKSkgKwogIGdndGl0bGUoIkRFQ0VQVElWRSBQUkFDVElDRSBDUklNRVMgQlkgRElTVFJJQ1QiKQpgYGAKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKCmdncGxvdChkYXRhID0gY2hpY2Fnb19jcmltZV9zdWJzZXQsIGFlcyh4PXByaW1hcnlfdHlwZSwgeT1kaXN0cmljdCwgZmlsbD1hcnJlc3QpKSArIAogIGdlb21fdGlsZSgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQpgYGAKCmBgYHtyfQojIENvcnJlbGF0aW9uCmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGNoaWNhZ29fY3JpbWVfc3Vic2V0LGFlcyh4PWRpc3RyaWN0LHk9cHJpbWFyeV90eXBlLGNvbG9yPWFycmVzdCkpK2dlb21fcG9pbnQoYWxwaGE9MC41KQpgYGAKCiMjIEFzc29jaWF0aW9uIFJ1bGVzCgpgYGB7cn0KY2hpY2Fnb19jcmltZV9zdWJzZXRfMiA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXQsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQpjaGljYWdvX2NyaW1lX3N1YnNldF8yIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF8yLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQp3cml0ZS5jc3YoY2hpY2Fnb19jcmltZV9zdWJzZXRfMiwiY2hpY2Fnb19jcmltZV9BUi5jc3YiLCBxdW90ZSA9IEZBTFNFLCByb3cubmFtZXMgPSBGQUxTRSkKbGlicmFyeShhcnVsZXMpCmNyaW1lX3RyYW5zYWN0aW9ucyA8LSByZWFkLnRyYW5zYWN0aW9ucygiY2hpY2Fnb19jcmltZV9BUi5jc3YiLCBzZXA9IiwiKQoKI2RlY2VwdGl2ZV9wcmFjdGljZV8yIDwtIHN1YnNldChkZWNlcHRpdmVfcHJhY3RpY2UsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQojd3JpdGUuY3N2KGRlY2VwdGl2ZV9wcmFjdGljZV8yLCJkZWNlcHRpdmVfcHJhY3RpY2UuY3N2IiwgcXVvdGUgPSBGQUxTRSwgcm93Lm5hbWVzID0gRkFMU0UpCiNkcF90cmFuc2FjdGlvbnMgPC0gcmVhZC50cmFuc2FjdGlvbnMoImRlY2VwdGl2ZV9wcmFjdGljZS5jc3YiLCBzZXA9IiwiKQpgYGAKYGBge3J9CmlmICghcmVxdWlyZSgiUkNvbG9yQnJld2VyIikpIHsKICAjIGluc3RhbGwgY29sb3IgcGFja2FnZSBvZiBSCiAgaW5zdGFsbC5wYWNrYWdlcygiUkNvbG9yQnJld2VyIikKICAjaW5jbHVkZSBsaWJyYXJ5IFJDb2xvckJyZXdlcgogIGxpYnJhcnkoUkNvbG9yQnJld2VyKQp9CgppdGVtRnJlcXVlbmN5UGxvdChjcmltZV90cmFuc2FjdGlvbnMsdG9wTj0yMCx0eXBlPSJhYnNvbHV0ZSIsCiAgICAgICAgICAgICAgICAgIGNvbD1icmV3ZXIucGFsKDgsJ1Bhc3RlbDInKSwgCiAgICAgICAgICAgICAgICAgIG1haW49IkFic29sdXRlIEl0ZW0gRnJlcXVlbmN5IFBsb3QiKQpgYGAKIyMgUmVnbGFzIGRlIEFzb2NpYWNpb24gR2VuZXJhbApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4gPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IGxpc3Qoc3VwcD0wLjAwMSwgY29uZj0wLjcpKQpzdWJzZXQucnVsZXMuY2xlYW4gPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4sIGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuKSkgPiAxKQpzdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4uIDwtIGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuWy1zdWJzZXQucnVsZXMuY2xlYW5dCmluc3BlY3Qoc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuLikKCnJ1bGVzX2J5X2NvdW50IDwtIHNvcnQoYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4sIGJ5ID0gImNvdW50IikKcnVsZXNfYnlfY29uZiA8LSBzb3J0KGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuLCBieSA9ICJjb25maWRlbmNlIikKcnVsZXNfYnlfc3VwcCA8LSBzb3J0KGFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuLCBieSA9ICJsaWZ0IikKaW5zcGVjdChydWxlc19ieV9jb3VudCkKaW5zcGVjdChydWxlc19ieV9jb25mKQppbnNwZWN0KHJ1bGVzX2J5X3N1cHApCmBgYApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucywgcGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC4xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iQVNTQVVMVCIpKQojIEJvcnJhciByZWdsYXMgcmVkdW5kYW50ZXMKYXNzYXVsdC5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlcywgYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlcykpID4gMSkgIyBnZXQgc3Vic2V0IHJ1bGVzIGluIHZlY3Rvcgphc3NhdWx0LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gYXNzYXVsdC5hc3NvY2lhdGlvbi5ydWxlc1stYXNzYXVsdC5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdChhc3NhdWx0LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgphc19ieV9jb3VudCA8LSBzb3J0KGFzc2F1bHQuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvdW50IikKYXNfYnlfY29uZiA8LSBzb3J0KGFzc2F1bHQuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KGFzX2J5X2NvdW50KQppbnNwZWN0KGFzX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KY2QuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iQ1JJTUlOQUwgREFNQUdFIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwpjZC5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoY2QuYXNzb2NpYXRpb24ucnVsZXMsIGNkLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gdmVjdG9yCmNkLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gY2QuYXNzb2NpYXRpb24ucnVsZXNbLWNkLnN1YnNldC5ydWxlc10gIyByZW1vdmUgc3Vic2V0IHJ1bGVzLgppbnNwZWN0KGNkLmFzc29jaWF0aW9uLnJ1bGVzKQoKY2RfYnlfY291bnQgPC0gc29ydChjZC5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpjZF9ieV9jb25mIDwtIHNvcnQoY2QuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KGNkX2J5X2NvdW50KQppbnNwZWN0KGNkX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KIyBSdWxlIEdFTkVSQVRJT04KZHAuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iREVDRVBUSVZFIFBSQUNUSUNFIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwpkcC5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQoZHAuYXNzb2NpYXRpb24ucnVsZXMsIGRwLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gdmVjdG9yCmRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gZHAuYXNzb2NpYXRpb24ucnVsZXNbLWRwLnN1YnNldC5ydWxlc10gIyByZW1vdmUgc3Vic2V0IHJ1bGVzLgppbnNwZWN0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgpkcF9ieV9jb3VudCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gImNvdW50IikKZHBfYnlfY29uZiA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KGRwX2J5X2NvdW50KQppbnNwZWN0KGRwX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KbmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzIDwtIGFwcmlvcmkoY3JpbWVfdHJhbnNhY3Rpb25zLCBwYXJhbWV0ZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc3VwcD0wLjAwMSwgY29uZj0wLjEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSJOQVJDT1RJQ1MiKSkKIyBCb3JyYXIgcmVnbGFzIHJlZHVuZGFudGVzCm5hcmNvdGljc19jbGVhbi5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQobmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzLCBuYXJjb3RpY3NfY2xlYW4uYXNzb2NpYXRpb24ucnVsZXMpKSA+IDEpICMgZ2V0IHN1YnNldCBydWxlcyBpbiB2ZWN0b3IKbmFyY290aWNzX2NsZWFuLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gbmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzWy1uYXJjb3RpY3NfY2xlYW4uc3Vic2V0LnJ1bGVzXSAjIHJlbW92ZSBzdWJzZXQgcnVsZXMuCmluc3BlY3QobmFyY290aWNzX2NsZWFuLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgpuYXJjX2J5X2NvdW50IDwtIHNvcnQobmFyY290aWNzX2NsZWFuLmFzc29jaWF0aW9uLnJ1bGVzLCBieSA9ICJjb3VudCIpCm5hcmNfYnlfY29uZiA8LSBzb3J0KG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY29uZmlkZW5jZSIpCiNkcF9ieV9zdXBwIDwtIHNvcnQoZHAuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgYnkgPSAic3VwcG9ydCIpCmluc3BlY3QobmFyY19ieV9jb3VudCkKaW5zcGVjdChuYXJjX2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0Kcm9iYmVyeS5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucywgcGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC4xNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZSA9IGxpc3QoZGVmYXVsdD0ibGhzIixyaHM9IlJPQkJFUlkiKSkKIyBCb3JyYXIgcmVnbGFzIHJlZHVuZGFudGVzCnJvYmJlcnkuc3Vic2V0LnJ1bGVzIDwtIHdoaWNoKGNvbFN1bXMoaXMuc3Vic2V0KHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMsIHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMpKSA+IDEpIApyb2JiZXJ5LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gcm9iYmVyeS5hc3NvY2lhdGlvbi5ydWxlc1stcm9iYmVyeS5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdChyb2JiZXJ5LmFzc29jaWF0aW9uLnJ1bGVzKQoKcm9iX2J5X2NvdW50IDwtIHNvcnQocm9iYmVyeS5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpyb2JfYnlfY29uZiA8LSBzb3J0KHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHJvYl9ieV9jb3VudCkKaW5zcGVjdChyb2JfYnlfY29uZikKI2luc3BlY3QoZHBfYnlfc3VwcCkKYGBgCmBgYHtyfQp0aGVmdC5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucywgcGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDUsIGNvbmY9MC41KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iVEhFRlQiKSkKIyBCb3JyYXIgcmVnbGFzIHJlZHVuZGFudGVzCnRoZWZ0LnN1YnNldC5ydWxlcyA8LSB3aGljaChjb2xTdW1zKGlzLnN1YnNldCh0aGVmdC5hc3NvY2lhdGlvbi5ydWxlcywgdGhlZnQuYXNzb2NpYXRpb24ucnVsZXMpKSA+IDEpIAp0aGVmdC5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzWy10aGVmdC5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdCh0aGVmdC5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKdGhlZnRfYnlfY291bnQgPC0gc29ydCh0aGVmdC5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQp0aGVmdF9ieV9jb25mIDwtIHNvcnQodGhlZnQuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojZHBfYnlfc3VwcCA8LSBzb3J0KGRwLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHRoZWZ0X2J5X2NvdW50KQppbnNwZWN0KHRoZWZ0X2J5X2NvbmYpCiNpbnNwZWN0KGRwX2J5X3N1cHApCmBgYApgYGB7cn0KdmMuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMsIHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMTUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSJWSU9MRU5UIENSSU1FIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwp2Yy5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQodmMuYXNzb2NpYXRpb24ucnVsZXMsIHZjLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gIAp2Yy5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHZjLmFzc29jaWF0aW9uLnJ1bGVzWy12Yy5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdCh2Yy5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKdmNfYnlfY291bnQgPC0gc29ydCh2Yy5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQp2Y19ieV9jb25mIDwtIHNvcnQodmMuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojdmNfYnlfc3VwcCA8LSBzb3J0KHZjLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHZjX2J5X2NvdW50KQppbnNwZWN0KHZjX2J5X2NvbmYpCiNpbnNwZWN0KHd2X2J5X3N1cHApCmBgYApgYGB7cn0Kd3YuYXNzb2NpYXRpb24ucnVsZXMgPC0gYXByaW9yaShjcmltZV90cmFuc2FjdGlvbnMscGFyYW1ldGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdChzdXBwPTAuMDAxLCBjb25mPTAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZSA9IGxpc3QoZGVmYXVsdD0ibGhzIixyaHM9IldFQVBPTlMgVklPTEFUSU9OIikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwp3di5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQod3YuYXNzb2NpYXRpb24ucnVsZXMsIHd2LmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gIAp3di5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHd2LmFzc29jaWF0aW9uLnJ1bGVzWy13di5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdCh3di5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKd3ZfYnlfY291bnQgPC0gc29ydCh3di5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQp3dl9ieV9jb25mIDwtIHNvcnQod3YuYXNzb2NpYXRpb24ucnVsZXMsIGJ5ID0gImNvbmZpZGVuY2UiKQojd3ZfYnlfc3VwcCA8LSBzb3J0KHd2LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHd2X2J5X2NvdW50KQppbnNwZWN0KHd2X2J5X2NvbmYpCiNpbnNwZWN0KHd2X2J5X3N1cHApCmBgYApgYGB7cn0KdHJ1ZS5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucyxwYXJhbWV0ZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDEsIGNvbmY9MC41KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlID0gbGlzdChkZWZhdWx0PSJsaHMiLHJocz0iVHJ1ZSIpKQojIEJvcnJhciByZWdsYXMgcmVkdW5kYW50ZXMKdHJ1ZS5zdWJzZXQucnVsZXMgPC0gd2hpY2goY29sU3Vtcyhpcy5zdWJzZXQodHJ1ZS5hc3NvY2lhdGlvbi5ydWxlcywgdHJ1ZS5hc3NvY2lhdGlvbi5ydWxlcykpID4gMSkgIyBnZXQgc3Vic2V0IHJ1bGVzIGluICAKdHJ1ZS5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuIDwtIHRydWUuYXNzb2NpYXRpb24ucnVsZXNbLXRydWUuc3Vic2V0LnJ1bGVzXSAjIHJlbW92ZSBzdWJzZXQgcnVsZXMuCmluc3BlY3QodHJ1ZS5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuKQoKdF9ieV9jb3VudCA8LSBzb3J0KHRydWUuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgYnkgPSAiY291bnQiKQp0X2J5X2NvbmYgPC0gc29ydCh0cnVlLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gImNvbmZpZGVuY2UiKQojd3ZfYnlfc3VwcCA8LSBzb3J0KHd2LnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4sIGJ5ID0gInN1cHBvcnQiKQppbnNwZWN0KHRfYnlfY291bnQpCmluc3BlY3QodF9ieV9jb25mKQojaW5zcGVjdCh3dl9ieV9zdXBwKQpgYGAKYGBge3J9CmZhbHNlLmFzc29jaWF0aW9uLnJ1bGVzIDwtIGFwcmlvcmkoY3JpbWVfdHJhbnNhY3Rpb25zLHBhcmFtZXRlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc3VwcD0wLjAwMSwgY29uZj0wLjgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSJGYWxzZSIpKQojIEJvcnJhciByZWdsYXMgcmVkdW5kYW50ZXMKZmFsc2Uuc3Vic2V0LnJ1bGVzIDwtIHdoaWNoKGNvbFN1bXMoaXMuc3Vic2V0KGZhbHNlLmFzc29jaWF0aW9uLnJ1bGVzLCBmYWxzZS5hc3NvY2lhdGlvbi5ydWxlcykpID4gMSkgIyBnZXQgc3Vic2V0IHJ1bGVzIGluICAKZmFsc2Uuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiA8LSBmYWxzZS5hc3NvY2lhdGlvbi5ydWxlc1stZmFsc2Uuc3Vic2V0LnJ1bGVzXSAjIHJlbW92ZSBzdWJzZXQgcnVsZXMuCmluc3BlY3QoZmFsc2Uuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLikKCmZfYnlfY291bnQgPC0gc29ydChmYWxzZS5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpmX2J5X2NvbmYgPC0gc29ydChmYWxzZS5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY29uZmlkZW5jZSIpCiN3dl9ieV9zdXBwIDwtIHNvcnQod3Yuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgYnkgPSAic3VwcG9ydCIpCmluc3BlY3QoZl9ieV9jb3VudCkKaW5zcGVjdChmX2J5X2NvbmYpCiNpbnNwZWN0KHd2X2J5X3N1cHApCmBgYApgYGB7cn0Kb2Noby5hc3NvY2lhdGlvbi5ydWxlcyA8LSBhcHJpb3JpKGNyaW1lX3RyYW5zYWN0aW9ucyxwYXJhbWV0ZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0KHN1cHA9MC4wMDAxLCBjb25mPTAuMDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVhcmFuY2UgPSBsaXN0KGRlZmF1bHQ9ImxocyIscmhzPSI4IikpCiMgQm9ycmFyIHJlZ2xhcyByZWR1bmRhbnRlcwpvY2hvLnN1YnNldC5ydWxlcyA8LSB3aGljaChjb2xTdW1zKGlzLnN1YnNldChvY2hvLmFzc29jaWF0aW9uLnJ1bGVzLCBvY2hvLmFzc29jaWF0aW9uLnJ1bGVzKSkgPiAxKSAjIGdldCBzdWJzZXQgcnVsZXMgaW4gIApvY2hvLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4gPC0gb2Noby5hc3NvY2lhdGlvbi5ydWxlc1stb2Noby5zdWJzZXQucnVsZXNdICMgcmVtb3ZlIHN1YnNldCBydWxlcy4KaW5zcGVjdChvY2hvLnN1YnNldC5hc3NvY2lhdGlvbi5ydWxlcy4pCgpvY2hvX2J5X2NvdW50IDwtIHNvcnQob2Noby5hc3NvY2lhdGlvbi5ydWxlcywgYnkgPSAiY291bnQiKQpvY2hvX2J5X2NvbmYgPC0gc29ydChvY2hvLmFzc29jaWF0aW9uLnJ1bGVzLCBieSA9ICJjb25maWRlbmNlIikKI3d2X2J5X3N1cHAgPC0gc29ydCh3di5zdWJzZXQuYXNzb2NpYXRpb24ucnVsZXMuLCBieSA9ICJzdXBwb3J0IikKaW5zcGVjdChvY2hvX2J5X2NvdW50KQppbnNwZWN0KG9jaG9fYnlfY29uZikKI2luc3BlY3Qod3ZfYnlfc3VwcCkKYGBgCgpgYGB7cn0KIyMgR1JBRklDT1MgCiMjIERhdGFzZXQgRW50ZXJvCmxpYnJhcnkoYXJ1bGVzVml6KQojIEZpbHRlciBydWxlcyB3aXRoIGNvbmZpZGVuY2UgZ3JlYXRlciB0aGFuIDAuNCBvciA0MCUKc3ViUnVsZXM8LWFzc29jaWF0aW9uLnJ1bGVzLmNsZWFuW3F1YWxpdHkoYXNzb2NpYXRpb24ucnVsZXMuY2xlYW4pJGNvbmZpZGVuY2U+MC43XQojUGxvdCBTdWJSdWxlcwpwbG90KHN1YlJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCiMjIFNlbGVjY2lvbmFtb3MgdW4gbnVtZXJvIGxpbWl0YWRvIGRlIHJlZ2xhcyBlbiBlbCBkYXRhc2V0IGxpbXBpbwp0b3AxMHN1YlJ1bGVzIDwtIGhlYWQoc3ViUnVsZXMsIG4gPSAyNSwgYnkgPSAiY29uZmlkZW5jZSIpCgojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHRvcDEwc3ViUnVsZXMsIG1ldGhvZCA9ICJncmFwaCIsICBlbmdpbmUgPSAiaHRtbHdpZGdldCIpCgojIyBJbmRpdmlkdWFsIFJ1bGUgUmVwcmVzZW50YXRpb24gRGF0YXNldCBMaW1waW8KIyBGaWx0ZXIgdG9wIDIwIHJ1bGVzIHdpdGggaGlnaGVzdCBsaWZ0CnN1YlJ1bGVzMjwtaGVhZChzdWJSdWxlcywgbj0yNSwgYnk9ImNvbmZpZGVuY2UiKQpwbG90KHN1YlJ1bGVzMiwgbWV0aG9kPSJwYXJhY29vcmQiKQoKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLixtZXRob2Q9InR3by1rZXkgcGxvdCIpCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgbiA9IDIwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgbWV0aG9kID0gImdyYXBoIiwgIGVuZ2luZSA9ICJodG1sd2lkZ2V0IikKCiMjIEluZGl2aWR1YWwgUnVsZSBSZXByZXNlbnRhdGlvbiBEYXRhc2V0IExpbXBpbwojIEZpbHRlciB0b3AgMjAgcnVsZXMgd2l0aCBoaWdoZXN0IGxpZnQKc3ViUnVsZXMyPC1oZWFkKGFzc2F1bHQuc3Vic2V0LmFzc29jaWF0aW9uLnJ1bGVzLiwgbj0yMCwgYnk9ImNvbmZpZGVuY2UiKQpwbG90KHRvcDEwc3ViUnVsZXMsIG1ldGhvZD0icGFyYWNvb3JkIikKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KGNkLmFzc29jaWF0aW9uLnJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCnN1YlJ1bGVzX2NkPC1jZC5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KGNkLmFzc29jaWF0aW9uLnJ1bGVzKSRjb25maWRlbmNlPjAuMl0KCiMjIFNlbGVjY2lvbmFtb3MgdW4gbnVtZXJvIGxpbWl0YWRvIGRlIHJlZ2xhcyBlbiBlbCBkYXRhc2V0IGxpbXBpbwp0b3AxMHN1YlJ1bGVzIDwtIGhlYWQoY2QuYXNzb2NpYXRpb24ucnVsZXMsIG4gPSAxMCwgYnkgPSAiY29uZmlkZW5jZSIpCmluc3BlY3QodG9wMTBzdWJSdWxlcykKIyBOb3csIHBsb3QgYW4gaW50ZXJhY3RpdmUgZ3JhcGg6CiNOb3RlOiBZb3UgY2FuIG1ha2UgYWxsIHlvdXIgcGxvdHMgaW50ZXJhY3RpdmUgdXNpbmcgZW5naW5lPWh0bWx3aWRnZXQgcGFyYW1ldGVyIGluIHBsb3QKcGxvdChzdWJSdWxlc19jZCwgbWV0aG9kID0gImdyYXBoIiwgIGVuZ2luZSA9ICJodG1sd2lkZ2V0IikKCiMjIEluZGl2aWR1YWwgUnVsZSBSZXByZXNlbnRhdGlvbiBEYXRhc2V0IExpbXBpbwojIEZpbHRlciB0b3AgMjAgcnVsZXMgd2l0aCBoaWdoZXN0IGxpZnQKc3ViUnVsZXMyPC1oZWFkKHN1YlJ1bGVzX2NkLCBuPTI1LCBieT0iY29uZmlkZW5jZSIpCnBsb3QodG9wMTBzdWJSdWxlcywgbWV0aG9kPSJwYXJhY29vcmQiKQpgYGAKYGBge3J9CiNQbG90IFN1YlJ1bGVzCnBsb3QoZHAuYXNzb2NpYXRpb24ucnVsZXMsbWV0aG9kPSJ0d28ta2V5IHBsb3QiKQoKc3ViUnVsZXNfZHA8LWRwLmFzc29jaWF0aW9uLnJ1bGVzW3F1YWxpdHkoZHAuYXNzb2NpYXRpb24ucnVsZXMpJGNvbmZpZGVuY2U+MC4xXQoKIyMgU2VsZWNjaW9uYW1vcyB1biBudW1lcm8gbGltaXRhZG8gZGUgcmVnbGFzIGVuIGVsIGRhdGFzZXQgbGltcGlvCnRvcDEwc3ViUnVsZXMgPC0gaGVhZChkcC5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb3VudCIpCgojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzX2RwLCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uIERhdGFzZXQgTGltcGlvCiMgRmlsdGVyIHRvcCAyMCBydWxlcyB3aXRoIGhpZ2hlc3QgbGlmdApzdWJSdWxlczI8LWhlYWQoc3ViUnVsZXNfZHAsIG49MjUsIGJ5PSJjb3VudCIpCnBsb3Qoc3ViUnVsZXNfZHAsIG1ldGhvZD0icGFyYWNvb3JkIikKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcyxtZXRob2Q9InR3by1rZXkgcGxvdCIpCgpzdWJSdWxlc19uYXJjb3RpY3M8LW5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcykkY29uZmlkZW5jZT4wLjZdCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKG5hcmNvdGljc19jbGVhbi5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb25maWRlbmNlIikKCiMgTm93LCBwbG90IGFuIGludGVyYWN0aXZlIGdyYXBoOgojTm90ZTogWW91IGNhbiBtYWtlIGFsbCB5b3VyIHBsb3RzIGludGVyYWN0aXZlIHVzaW5nIGVuZ2luZT1odG1sd2lkZ2V0IHBhcmFtZXRlciBpbiBwbG90CnBsb3Qoc3ViUnVsZXNfbmFyY290aWNzLCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uIERhdGFzZXQgTGltcGlvCiMgRmlsdGVyIHRvcCAyMCBydWxlcyB3aXRoIGhpZ2hlc3QgbGlmdApzdWJSdWxlczI8LWhlYWQoc3ViUnVsZXNfbmFyY290aWNzLCBuPTI1LCBieT0iY29uZmlkZW5jZSIpCnBsb3Qoc3ViUnVsZXNfbmFyY290aWNzLCBtZXRob2Q9InBhcmFjb29yZCIpCmBgYApgYGB7cn0KI1Bsb3QgU3ViUnVsZXMKcGxvdChyb2JiZXJ5LmFzc29jaWF0aW9uLnJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCnN1YlJ1bGVzX3JvYmJlcnk8LXJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXNbcXVhbGl0eShyb2JiZXJ5LmFzc29jaWF0aW9uLnJ1bGVzKSRjb25maWRlbmNlPjAuMTVdCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKHJvYmJlcnkuYXNzb2NpYXRpb24ucnVsZXMsIG4gPSAxMCwgYnkgPSAiY29uZmlkZW5jZSIpCmluc3BlY3QodG9wMTBzdWJSdWxlcykKIyBOb3csIHBsb3QgYW4gaW50ZXJhY3RpdmUgZ3JhcGg6CiNOb3RlOiBZb3UgY2FuIG1ha2UgYWxsIHlvdXIgcGxvdHMgaW50ZXJhY3RpdmUgdXNpbmcgZW5naW5lPWh0bWx3aWRnZXQgcGFyYW1ldGVyIGluIHBsb3QKcGxvdChzdWJSdWxlc19yb2JiZXJ5LCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uIERhdGFzZXQgTGltcGlvCiMgRmlsdGVyIHRvcCAyMCBydWxlcyB3aXRoIGhpZ2hlc3QgbGlmdApzdWJSdWxlczI8LWhlYWQoc3ViUnVsZXNfcm9iYmVyeSwgbj0yNSwgYnk9ImNvbmZpZGVuY2UiKQpwbG90KHRvcDEwc3ViUnVsZXMsIG1ldGhvZD0icGFyYWNvb3JkIikKYGBgCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzLG1ldGhvZD0idHdvLWtleSBwbG90IikKCnN1YlJ1bGVzX3RoZWZ0PC10aGVmdC5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzKSRjb25maWRlbmNlPjAuNDVdCgojIyBTZWxlY2Npb25hbW9zIHVuIG51bWVybyBsaW1pdGFkbyBkZSByZWdsYXMgZW4gZWwgZGF0YXNldCBsaW1waW8KdG9wMTBzdWJSdWxlcyA8LSBoZWFkKHRoZWZ0LmFzc29jaWF0aW9uLnJ1bGVzLCBuID0gMTAsIGJ5ID0gImNvbmZpZGVuY2UiKQppbnNwZWN0KHRvcDEwc3ViUnVsZXMpCiMgTm93LCBwbG90IGFuIGludGVyYWN0aXZlIGdyYXBoOgojTm90ZTogWW91IGNhbiBtYWtlIGFsbCB5b3VyIHBsb3RzIGludGVyYWN0aXZlIHVzaW5nIGVuZ2luZT1odG1sd2lkZ2V0IHBhcmFtZXRlciBpbiBwbG90CnBsb3Qoc3ViUnVsZXNfdGhlZnQsIG1ldGhvZCA9ICJncmFwaCIsICBlbmdpbmUgPSAiaHRtbHdpZGdldCIpCgojIyBJbmRpdmlkdWFsIFJ1bGUgUmVwcmVzZW50YXRpb24KcGxvdCh0b3AxMHN1YlJ1bGVzLCBtZXRob2Q9InBhcmFjb29yZCIpCmBgYApgYGB7cn0KI1Bsb3QgU3ViUnVsZXMKcGxvdCh2Yy5hc3NvY2lhdGlvbi5ydWxlcyxtZXRob2Q9InR3by1rZXkgcGxvdCIpCgpzdWJSdWxlc192YzwtdmMuYXNzb2NpYXRpb24ucnVsZXNbcXVhbGl0eSh2Yy5hc3NvY2lhdGlvbi5ydWxlcykkY29uZmlkZW5jZT4wLjE1XQoKIyMgU2VsZWNjaW9uYW1vcyB1biBudW1lcm8gbGltaXRhZG8gZGUgcmVnbGFzIGVuIGVsIGRhdGFzZXQgbGltcGlvCnRvcDEwc3ViUnVsZXMgPC0gaGVhZCh2Yy5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzX3ZjLCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uCnBsb3QodG9wMTBzdWJSdWxlcywgbWV0aG9kPSJwYXJhY29vcmQiKQpgYGAKYGBge3J9CiNQbG90IFN1YlJ1bGVzCnBsb3Qod3YuYXNzb2NpYXRpb24ucnVsZXMsbWV0aG9kPSJ0d28ta2V5IHBsb3QiKQoKc3ViUnVsZXNfd3Y8LXd2LmFzc29jaWF0aW9uLnJ1bGVzW3F1YWxpdHkod3YuYXNzb2NpYXRpb24ucnVsZXMpJGNvbmZpZGVuY2U+MC4xXQoKIyMgU2VsZWNjaW9uYW1vcyB1biBudW1lcm8gbGltaXRhZG8gZGUgcmVnbGFzIGVuIGVsIGRhdGFzZXQgbGltcGlvCnRvcDEwc3ViUnVsZXMgPC0gaGVhZCh3di5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDEwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzX3d2LCBtZXRob2QgPSAiZ3JhcGgiLCAgZW5naW5lID0gImh0bWx3aWRnZXQiKQoKIyMgSW5kaXZpZHVhbCBSdWxlIFJlcHJlc2VudGF0aW9uCnBsb3QodG9wMTBzdWJSdWxlcywgbWV0aG9kPSJwYXJhY29vcmQiKQpgYGAKCmBgYHtyfQojUGxvdCBTdWJSdWxlcwpwbG90KG9jaG8uYXNzb2NpYXRpb24ucnVsZXMsbWV0aG9kPSJ0d28ta2V5IHBsb3QiKQoKc3ViUnVsZXNfODwtb2Noby5hc3NvY2lhdGlvbi5ydWxlc1txdWFsaXR5KG9jaG8uYXNzb2NpYXRpb24ucnVsZXMpJGNvbmZpZGVuY2U+MC4wMV0KCiMjIFNlbGVjY2lvbmFtb3MgdW4gbnVtZXJvIGxpbWl0YWRvIGRlIHJlZ2xhcyBlbiBlbCBkYXRhc2V0IGxpbXBpbwp0b3AxMHN1YlJ1bGVzIDwtIGhlYWQob2Noby5hc3NvY2lhdGlvbi5ydWxlcywgbiA9IDIwLCBieSA9ICJjb25maWRlbmNlIikKaW5zcGVjdCh0b3AxMHN1YlJ1bGVzKQojIE5vdywgcGxvdCBhbiBpbnRlcmFjdGl2ZSBncmFwaDoKI05vdGU6IFlvdSBjYW4gbWFrZSBhbGwgeW91ciBwbG90cyBpbnRlcmFjdGl2ZSB1c2luZyBlbmdpbmU9aHRtbHdpZGdldCBwYXJhbWV0ZXIgaW4gcGxvdApwbG90KHN1YlJ1bGVzXzgsIG1ldGhvZCA9ICJncmFwaCIsICBlbmdpbmUgPSAiaHRtbHdpZGdldCIpCgojIyBJbmRpdmlkdWFsIFJ1bGUgUmVwcmVzZW50YXRpb24KcGxvdCh0b3AxMHN1YlJ1bGVzLCBtZXRob2Q9InBhcmFjb29yZCIpCmBgYAoKIyMgTWFwYXMgZGUgRGVuc2lkYWQKCmBgYHtyfQojIyBJTklUSUFMSVpFCmxpYnJhcnkoImxlYWZsZXQiKQpsaWJyYXJ5KCJkYXRhLnRhYmxlIikKbGlicmFyeSgic3AiKQpsaWJyYXJ5KCJyZ2RhbCIpCiMgbGlicmFyeSgibWFwdG9vbHMiKQpsaWJyYXJ5KCJLZXJuU21vb3RoIikKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKCmFzc2F1bHQgPC0gbmEub21pdChhc3NhdWx0KQpzZXREVChhc3NhdWx0KQpjcmltaW5hbF9kYW1hZ2UgPC0gbmEub21pdChjcmltaW5hbF9kYW1hZ2UpCnNldERUKGNyaW1pbmFsX2RhbWFnZSkKZGVjZXB0aXZlX3ByYWN0aWNlIDwtIG5hLm9taXQoZGVjZXB0aXZlX3ByYWN0aWNlKQpzZXREVChkZWNlcHRpdmVfcHJhY3RpY2UpCm5hcmNvdGljcyA8LSBuYS5vbWl0KG5hcmNvdGljcykKc2V0RFQobmFyY290aWNzKQpyb2JiZXJ5IDwtIG5hLm9taXQocm9iYmVyeSkKc2V0RFQocm9iYmVyeSkKdGhlZnQgPC0gbmEub21pdCh0aGVmdCkKc2V0RFQodGhlZnQpCnZpb2xlbnRfY3JpbWUgPC0gbmEub21pdCh2aW9sZW50X2NyaW1lKQpzZXREVCh2aW9sZW50X2NyaW1lKQp3ZWFwb25zX3Zpb2xhdGlvbiA8LSBuYS5vbWl0KHdlYXBvbnNfdmlvbGF0aW9uKQpzZXREVCh3ZWFwb25zX3Zpb2xhdGlvbikKCiMjIE1BS0UgQ09OVE9VUiBMSU5FUwojIyBBc3NhdWx0CmtkZV9hc3NhdWx0IDwtIGJrZGUyRChhc3NhdWx0WyAsIGxpc3QobG9uZ2l0dWRlLCBsYXRpdHVkZSldLAogICAgICAgICAgICAgIGJhbmR3aWR0aD1jKC4wMDAxLCAuMDAwMSksIGdyaWRzaXplID0gYyg3NSw3NSkpCkNMX2Fzc2F1bHQgPC0gY29udG91ckxpbmVzKGtkZV9hc3NhdWx0JHgxICwga2RlX2Fzc2F1bHQkeDIgLCBrZGVfYXNzYXVsdCRmaGF0KQoKIyMgRVhUUkFDVCBDT05UT1VSIExJTkUgTEVWRUxTCkxFVlNfYXNzYXVsdDwtIGFzLmZhY3RvcihzYXBwbHkoQ0xfYXNzYXVsdCwgYFtbYCwgImxldmVsIikpCk5MRVZfYXNzYXVsdCA8LSBsZW5ndGgobGV2ZWxzKExFVlNfYXNzYXVsdCkpCgojIyBDT05WRVJUIENPTlRPVVIgTElORVMgVE8gUE9MWUdPTlMKcGdvbnNfYXNzYXVsdCA8LSBsYXBwbHkoMTpsZW5ndGgoQ0xfYXNzYXVsdCksIGZ1bmN0aW9uKGkpCiAgICBQb2x5Z29ucyhsaXN0KFBvbHlnb24oY2JpbmQoQ0xfYXNzYXVsdFtbaV1dJHgsIENMX2Fzc2F1bHRbW2ldXSR5KSkpLCBJRD1pKSkKc3Bnb25zX2Fzc2F1bHQgPSBTcGF0aWFsUG9seWdvbnMocGdvbnNfYXNzYXVsdCkKCiMjIENyaW1pbmFsIERhbWFnZQprZGVfY2QgPC0gYmtkZTJEKGNyaW1pbmFsX2RhbWFnZVsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF9jZCA8LSBjb250b3VyTGluZXMoa2RlX2NkJHgxICwga2RlX2NkJHgyICwga2RlX2NkJGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU19jZDwtIGFzLmZhY3RvcihzYXBwbHkoQ0xfY2QsIGBbW2AsICJsZXZlbCIpKQpOTEVWX2NkIDwtIGxlbmd0aChsZXZlbHMoTEVWU19jZCkpCgojIyBDT05WRVJUIENPTlRPVVIgTElORVMgVE8gUE9MWUdPTlMKcGdvbnNfY2QgPC0gbGFwcGx5KDE6bGVuZ3RoKENMX2NkKSwgZnVuY3Rpb24oaSkKICAgIFBvbHlnb25zKGxpc3QoUG9seWdvbihjYmluZChDTF9jZFtbaV1dJHgsIENMX2NkW1tpXV0keSkpKSwgSUQ9aSkpCnNwZ29uc19jZCA9IFNwYXRpYWxQb2x5Z29ucyhwZ29uc19jZCkKCiMjIERlY2VwdGl2ZSBQcmFjdGljZQprZGVfZHAgPC0gYmtkZTJEKGRlY2VwdGl2ZV9wcmFjdGljZVsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF9kcCA8LSBjb250b3VyTGluZXMoa2RlX2RwJHgxICwga2RlX2RwJHgyICwga2RlX2RwJGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU19kcDwtIGFzLmZhY3RvcihzYXBwbHkoQ0xfZHAsIGBbW2AsICJsZXZlbCIpKQpOTEVWX2RwIDwtIGxlbmd0aChsZXZlbHMoTEVWU19kcCkpCgojIyBDT05WRVJUIENPTlRPVVIgTElORVMgVE8gUE9MWUdPTlMKcGdvbnNfZHAgPC0gbGFwcGx5KDE6bGVuZ3RoKENMX2RwKSwgZnVuY3Rpb24oaSkKICAgIFBvbHlnb25zKGxpc3QoUG9seWdvbihjYmluZChDTF9kcFtbaV1dJHgsIENMX2RwW1tpXV0keSkpKSwgSUQ9aSkpCnNwZ29uc19kcCA9IFNwYXRpYWxQb2x5Z29ucyhwZ29uc19kcCkKCiMjIE5hcmNvdGljcwprZGVfbmFyY290aWNzIDwtIGJrZGUyRChuYXJjb3RpY3NbICwgbGlzdChsb25naXR1ZGUsIGxhdGl0dWRlKV0sCiAgICAgICAgICAgICAgYmFuZHdpZHRoPWMoLjAwMDEsIC4wMDAxKSwgZ3JpZHNpemUgPSBjKDc1LDc1KSkKQ0xfbmFyY290aWNzIDwtIGNvbnRvdXJMaW5lcyhrZGVfbmFyY290aWNzJHgxICwga2RlX25hcmNvdGljcyR4MiAsIGtkZV9uYXJjb3RpY3MkZmhhdCkKCiMjIEVYVFJBQ1QgQ09OVE9VUiBMSU5FIExFVkVMUwpMRVZTX25hcmNvdGljcyA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX25hcmNvdGljcywgYFtbYCwgImxldmVsIikpCk5MRVZfbmFyY290aWNzIDwtIGxlbmd0aChsZXZlbHMoTEVWU19uYXJjb3RpY3MpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX25hcmNvdGljcyA8LSBsYXBwbHkoMTpsZW5ndGgoQ0xfbmFyY290aWNzKSwgZnVuY3Rpb24oaSkKICAgIFBvbHlnb25zKGxpc3QoUG9seWdvbihjYmluZChDTF9uYXJjb3RpY3NbW2ldXSR4LCBDTF9uYXJjb3RpY3NbW2ldXSR5KSkpLCBJRD1pKSkKc3Bnb25zX25hcmNvdGljcyA9IFNwYXRpYWxQb2x5Z29ucyhwZ29uc19uYXJjb3RpY3MpCgojIyBSb2JiZXJ5CmtkZV9yb2JiZXJ5IDwtIGJrZGUyRChyb2JiZXJ5WyAsIGxpc3QobG9uZ2l0dWRlLCBsYXRpdHVkZSldLAogICAgICAgICAgICAgIGJhbmR3aWR0aD1jKC4wMDAxLCAuMDAwMSksIGdyaWRzaXplID0gYyg3NSw3NSkpCkNMX3JvYmJlcnkgPC0gY29udG91ckxpbmVzKGtkZV9yb2JiZXJ5JHgxICwga2RlX3JvYmJlcnkkeDIgLCBrZGVfcm9iYmVyeSRmaGF0KQoKIyMgRVhUUkFDVCBDT05UT1VSIExJTkUgTEVWRUxTCkxFVlNfcm9iYmVyeSA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX3JvYmJlcnksIGBbW2AsICJsZXZlbCIpKQpOTEVWX3JvYmJlcnkgPC0gbGVuZ3RoKGxldmVscyhMRVZTX3JvYmJlcnkpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX3JvYmJlcnkgPC0gbGFwcGx5KDE6bGVuZ3RoKENMX3JvYmJlcnkpLCBmdW5jdGlvbihpKQogICAgUG9seWdvbnMobGlzdChQb2x5Z29uKGNiaW5kKENMX3JvYmJlcnlbW2ldXSR4LCBDTF9yb2JiZXJ5W1tpXV0keSkpKSwgSUQ9aSkpCnNwZ29uc19yb2JiZXJ5ID0gU3BhdGlhbFBvbHlnb25zKHBnb25zX3JvYmJlcnkpCgojIyBUaGVmdHMKa2RlX3RoZWZ0IDwtIGJrZGUyRCh0aGVmdFsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF90aGVmdCA8LSBjb250b3VyTGluZXMoa2RlX3RoZWZ0JHgxICwga2RlX3RoZWZ0JHgyICwga2RlX3RoZWZ0JGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU190aGVmdCA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX3RoZWZ0LCBgW1tgLCAibGV2ZWwiKSkKTkxFVl90aGVmdCA8LSBsZW5ndGgobGV2ZWxzKExFVlNfdGhlZnQpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX3RoZWZ0IDwtIGxhcHBseSgxOmxlbmd0aChDTF90aGVmdCksIGZ1bmN0aW9uKGkpCiAgICBQb2x5Z29ucyhsaXN0KFBvbHlnb24oY2JpbmQoQ0xfdGhlZnRbW2ldXSR4LCBDTF90aGVmdFtbaV1dJHkpKSksIElEPWkpKQpzcGdvbnNfdGhlZnQgPSBTcGF0aWFsUG9seWdvbnMocGdvbnNfdGhlZnQpCgojIyBWaW9sZW50IENyaW13cwprZGVfdmMgPC0gYmtkZTJEKHZpb2xlbnRfY3JpbWVbICwgbGlzdChsb25naXR1ZGUsIGxhdGl0dWRlKV0sCiAgICAgICAgICAgICAgYmFuZHdpZHRoPWMoLjAwMDEsIC4wMDAxKSwgZ3JpZHNpemUgPSBjKDc1LDc1KSkKQ0xfdmMgPC0gY29udG91ckxpbmVzKGtkZV92YyR4MSAsIGtkZV92YyR4MiAsIGtkZV92YyRmaGF0KQoKIyMgRVhUUkFDVCBDT05UT1VSIExJTkUgTEVWRUxTCkxFVlNfdmMgPC0gYXMuZmFjdG9yKHNhcHBseShDTF92YywgYFtbYCwgImxldmVsIikpCk5MRVZfdmMgPC0gbGVuZ3RoKGxldmVscyhMRVZTX3ZjKSkKCiMjIENPTlZFUlQgQ09OVE9VUiBMSU5FUyBUTyBQT0xZR09OUwpwZ29uc192YyA8LSBsYXBwbHkoMTpsZW5ndGgoQ0xfdmMpLCBmdW5jdGlvbihpKQogICAgUG9seWdvbnMobGlzdChQb2x5Z29uKGNiaW5kKENMX3ZjW1tpXV0keCwgQ0xfdmNbW2ldXSR5KSkpLCBJRD1pKSkKc3Bnb25zX3ZjID0gU3BhdGlhbFBvbHlnb25zKHBnb25zX3ZjKQoKIyMgV2VhcG9ucyBWaW9sYXRpb24Ka2RlX3d2IDwtIGJrZGUyRCh3ZWFwb25zX3Zpb2xhdGlvblsgLCBsaXN0KGxvbmdpdHVkZSwgbGF0aXR1ZGUpXSwKICAgICAgICAgICAgICBiYW5kd2lkdGg9YyguMDAwMSwgLjAwMDEpLCBncmlkc2l6ZSA9IGMoNzUsNzUpKQpDTF93diA8LSBjb250b3VyTGluZXMoa2RlX3d2JHgxICwga2RlX3d2JHgyICwga2RlX3d2JGZoYXQpCgojIyBFWFRSQUNUIENPTlRPVVIgTElORSBMRVZFTFMKTEVWU193diA8LSBhcy5mYWN0b3Ioc2FwcGx5KENMX3d2LCBgW1tgLCAibGV2ZWwiKSkKTkxFVl93diA8LSBsZW5ndGgobGV2ZWxzKExFVlNfd3YpKQoKIyMgQ09OVkVSVCBDT05UT1VSIExJTkVTIFRPIFBPTFlHT05TCnBnb25zX3d2IDwtIGxhcHBseSgxOmxlbmd0aChDTF93diksIGZ1bmN0aW9uKGkpCiAgICBQb2x5Z29ucyhsaXN0KFBvbHlnb24oY2JpbmQoQ0xfd3ZbW2ldXSR4LCBDTF93dltbaV1dJHkpKSksIElEPWkpKQpzcGdvbnNfd3YgPSBTcGF0aWFsUG9seWdvbnMocGdvbnNfd3YpCgpsZWFmbGV0KCkgJT4lIGFkZFRpbGVzKCkgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX25hcmNvdGljcywgY29sb3IgPSBicmV3ZXIucGFsKE5MRVZfbmFyY290aWNzLCBuYW1lID0gIllsT3JSZCIpW0xFVlNfbmFyY290aWNzXSwgZ3JvdXAgPSAiTmFyY290aWNzIikgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX2Fzc2F1bHQsIGNvbG9yID0gYnJld2VyLnBhbChOTEVWX2Fzc2F1bHQsIG5hbWUgPSAiUmVkcyIpW0xFVlNfYXNzYXVsdF0sIGdyb3VwID0gIkFzc2F1bHQiKSAlPiUKICAgIGFkZFBvbHlnb25zKGRhdGEgPSBzcGdvbnNfY2QsIGNvbG9yID0gYnJld2VyLnBhbChOTEVWX2NkLCBuYW1lPSJZbEduQnUiKVtMRVZTX2NkXSwgZ3JvdXAgPSAiQ3JpbWluYWwgRGFtYWdlIikgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX2RwLCBjb2xvciA9IGJyZXdlci5wYWwoTkxFVl9kcCwgbmFtZSA9ICJZbEduIilbTEVWU19kcF0sIGdyb3VwID0gIkRlY2VwdGl2ZSBQcmFjdGljZSIpICU+JQogICAgYWRkUG9seWdvbnMoZGF0YSA9IHNwZ29uc19yb2JiZXJ5LCBjb2xvciA9IGJyZXdlci5wYWwoTkxFVl9yb2JiZXJ5LCBuYW1lID0gIlB1cnBsZXMiKVtMRVZTX3JvYmJlcnldLCBncm91cCA9ICJSb2JiZXJ5IikgJT4lCiAgICBhZGRQb2x5Z29ucyhkYXRhID0gc3Bnb25zX3RoZWZ0LCBjb2xvciA9IGJyZXdlci5wYWwoTkxFVl90aGVmdCwgbmFtZSA9ICJPcmFuZ2VzIilbTEVWU190aGVmdF0sIGdyb3VwID0gIlRoZWZ0cyIpICU+JQogICAgYWRkUG9seWdvbnMoZGF0YSA9IHNwZ29uc192YywgY29sb3IgPSBicmV3ZXIucGFsKE5MRVZfdmMsIG5hbWUgPSAiR3JleXMiKVtMRVZTX3ZjXSwgZ3JvdXAgPSAiVmlvbGVudCBDcmltZXMiKSAlPiUKICAgIGFkZFBvbHlnb25zKGRhdGEgPSBzcGdvbnNfd3YsIGNvbG9yID0gYnJld2VyLnBhbChOTEVWX3d2LCBuYW1lID0gIkJsdWVzIilbTEVWU193dl0sIGdyb3VwID0gIldlYXBvbnMgVmlvbGF0aW9uIikgJT4lCiAgICBhZGRMYWJlbE9ubHlNYXJrZXJzKGRpc3RyaWN0cyRsb25naXR1ZGUsIGRpc3RyaWN0cyRsYXRpdHVkZSwgbGFiZWwgPSAgZGlzdHJpY3RzJGRpc3RyaWN0LCAKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsT3B0aW9ucyA9IGxhYmVsT3B0aW9ucyhub0hpZGUgPSBULCBkaXJlY3Rpb24gPSAndG9wJywgdGV4dE9ubHkgPSBUKSwgZ3JvdXAgPSAiRGlzdHJpY3RzIikgJT4lCiAgICBhZGRMYXllcnNDb250cm9sKG92ZXJsYXlHcm91cHMgPSBjKCJBc3NhdWx0IiwgIkNyaW1pbmFsIERhbWFnZSIsIkRlY2VwdGl2ZSBQcmFjdGljZSIsICJOYXJjb3RpY3MiLCJSb2JiZXJ5IiwiVGhlZnRzIiwiVmlvbGVudCBDcmltZXMiLCJXZWFwb25zIFZpb2xhdGlvbiIsICJEaXN0cmljdHMiKSxvcHRpb25zID0gbGF5ZXJzQ29udHJvbE9wdGlvbnMoY29sbGFwc2VkID0gRkFMU0UpKQogICAgCiNhZGRDaXJjbGVzKGxuZyA9IG5hcmNvdGljcyRsb25naXR1ZGUsIGxhdCA9IG5hcmNvdGljcyRsYXRpdHVkZSxyYWRpdXMgPSAuMSwgb3BhY2l0eSA9IC40LCBjb2wgPSAiYmx1ZSIsIGdyb3VwID0gIlBvaW50cyIpICU+JQoKCmBgYApgYGB7cn0KI2xlYWZsZXQoKSAlPiUgYWRkVGlsZXMoKSAlPiUKIyAgICBhZGRDaXJjbGVzKGxuZyA9IHdlYXBvbnNfdmlvbGF0aW9uJGxvbmdpdHVkZSwgbGF0ID0gd2VhcG9uc192aW9sYXRpb24kbGF0aXR1ZGUscmFkaXVzID0gLjA1LCBvcGFjaXR5ID0gMC4xLCBjb2wgPSBicmV3ZXIucGFsKDEwLG5hbWUgPSAiUmVkcyIpLCBncm91cCA9ICJOYXJjb3RpY3MiKSAlPiUKIyAgICBhZGRMYWJlbE9ubHlNYXJrZXJzKGRpc3RyaWN0cyRsb25naXR1ZGUsIGRpc3RyaWN0cyRsYXRpdHVkZSwgbGFiZWwgPSAgZGlzdHJpY3RzJGRpc3RyaWN0LCAKIyAgICAgICAgICAgICAgICAgICAgICBsYWJlbE9wdGlvbnMgPSBsYWJlbE9wdGlvbnMobm9IaWRlID0gVCwgZGlyZWN0aW9uID0gJ3RvcCcsIHRleHRPbmx5ID0gVCwgdGV4dHNpemUgPSAiMTVweCIpLCBncm91cCA9ICMiRGlzdHJpY3RzIikgJT4lCiMgICAgYWRkTGF5ZXJzQ29udHJvbChvdmVybGF5R3JvdXBzID0gYygiQXNzYXVsdCIsICJDcmltaW5hbCBEYW1hZ2UiLCJEZWNlcHRpdmUgUHJhY3RpY2UiLCAiTmFyY290aWNzIiwiUm9iYmVyeSIsIlRoZWZ0cyIsIlZpb2xlbnQgQ3JpbWVzIiwiV2VhcG9ucyBWaW9sYXRpb24iLCAiRGlzdHJpY3RzIiksb3B0aW9ucyA9IGxheWVyc0NvbnRyb2xPcHRpb25zKGNvbGxhcHNlZCA9IEZBTFNFKSkKCmBgYAojIyBDbHVzdGVyaW5nIApgYGB7cn0KY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uLGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCnVuaXF1ZShjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlKQoKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KG1sdG9vbHMpCiNDcmltZV9jaGljYWdvX2R1bW15IDwtIG9uZV9ob3QoYXMuZGF0YS50YWJsZShDcmltZV9jaGljYWdvX2RlZl9jbHVzdCkpCgp0eXBlcyA8LSB1bmlxdWUoY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSkKY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSA8LSBtYXRjaChjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlLCB1bmlxdWUoY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSkpCmNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRhcnJlc3QgPC0gbWF0Y2goY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJGFycmVzdCwgdW5pcXVlKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRhcnJlc3QpKQojY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCmNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRkaXN0cmljdCA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRkaXN0cmljdCkKdGVzdCA8LSBjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmcKI05vcm1hbGl6YXRpb24gb2YgdmFyaWFibGVzCmxpYnJhcnkoUlNOTlMpCgp0cmFpbl9zZXQgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKdHJhaW5fc2V0JHByaW1hcnlfdHlwZSA8LSBtYXRjaCh0cmFpbl9zZXQkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fc2V0JHByaW1hcnlfdHlwZSkpCnRyYWluX3NldCRhcnJlc3QgPC0gbWF0Y2godHJhaW5fc2V0JGFycmVzdCwgdW5pcXVlKHRyYWluX3NldCRhcnJlc3QpKQojdHJhaW5fc2V0JGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIG1hdGNoKHRyYWluX3NldCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX3NldCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRyYWluX3NldCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX3NldCRkaXN0cmljdCkKCiNpbmRleCA8LSBzYW1wbGUobnJvdyhjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmdfY3V0KSwgcm91bmQoMC43NSpucm93KGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZ19jdXQpKSkKI3RyYWluIDwtIENyaW1lX2NoaWNhZ29fZGVmX2NsdXN0X2N1dFtpbmRleCxdIAojdGVzdCA8LSBDcmltZV9jaGljYWdvX2RlZl9jbHVzdF9jdXRbLWluZGV4LF0KdHJhaW5fbGFiZWwgPC0gdHJhaW5fc2V0WywxXQp0ZXN0X2xhYmVsIDwtIHRlc3RbLDFdCgojT3B0aW11bSBudW1iZXIgb2YgY2x1c3RlcnMuIEVsYm93IG1ldGhvZAojIEFsdGVybmF0aXZlIHVzaW5nIGZ2aXogZnVuY3Rpb24gZm9yIEVsYm93IG1ldGhvZApsaWJyYXJ5KGZhY3RvZXh0cmEpCmxpYnJhcnkoTmJDbHVzdCkKc2V0LnNlZWQoMTIzKQp0cmFpbl9zbWFsbCA8LSB0cmFpbl9zZXRbMToxMDAwLF0KdGVzdF9zbWFsbCA8LSB0ZXN0WzE6MTAwLF0KCiMjIERlbmRvZ3JhbXMKbGlicmFyeSh0aWR5dmVyc2UpICAgICAgI2RhdGEgbWFuaXB1bGF0aW9uIGFuZCB2aXN1YWxpemF0aW9uCmxpYnJhcnkoY2xhc3MpICAgICAgICAgICMgdG8gY2FsbCBjbGFzcyBwYWNrYWdlIGZvciBrTk4KbGlicmFyeShjYXJldCkKbGlicmFyeShjbHVzdGVyKQojIERpdmlzaXZlIEhpZXJhcmNoaWNhbCBDbHVzdGVyaW5nIC0gZGlhbmEKIyBjb21wdXRlIGRpdmlzaXZlIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nCmRpdiA8LSBkaWFuYSh0cmFpbl9zbWFsbCkKcGxvdChkaXYsIG1haW4gPSAiRGl2aXNpdmUiKQoKZGlzdGFuY2UgPC0gZGlzdCh0cmFpbl9zbWFsbCxtZXRob2QgPSAiZXVjbGlkZWFuIikKYWdnIDwtIGhjbHVzdChkaXN0YW5jZSwgbWV0aG9kID0gImNvbXBsZXRlIikKcGxvdChhZ2csCiAgICAgbWFpbiA9ICJBZ2dsb21lcmF0aXZlLCBjb21wbGV0ZSBsaW5rYWdlcyIpCgpsaWJyYXJ5KGZwYykKY3N0YXRzLnRhYmxlIDwtIGZ1bmN0aW9uKGRpc3QsIHRyZWUsIGspIHsKY2x1c3QuYXNzZXNzIDwtIGMoImNsdXN0ZXIubnVtYmVyIiwibiIsIndpdGhpbi5jbHVzdGVyLnNzIiwiYXZlcmFnZS53aXRoaW4iLCJhdmVyYWdlLmJldHdlZW4iLAogICAgICAgICAgICAgICAgICAid2IucmF0aW8iLCJkdW5uMiIsImF2Zy5zaWx3aWR0aCIpCmNsdXN0LnNpemUgPC0gYygiY2x1c3Rlci5zaXplIikKc3RhdHMubmFtZXMgPC0gYygpCnJvdy5jbHVzdCA8LSBjKCkKb3V0cHV0LnN0YXRzIDwtIG1hdHJpeChuY29sID0gaywgbnJvdyA9IGxlbmd0aChjbHVzdC5hc3Nlc3MpKQpjbHVzdGVyLnNpemVzIDwtIG1hdHJpeChuY29sID0gaywgbnJvdyA9IGspCmZvcihpIGluIGMoMTprKSl7CiAgcm93LmNsdXN0W2ldIDwtIHBhc3RlKCJDbHVzdGVyLSIsIGksICIgc2l6ZSIpCn0KZm9yKGkgaW4gYygyOmspKXsKICBzdGF0cy5uYW1lc1tpXSA8LSBwYXN0ZSgiVGVzdCIsIGktMSkKICAKICBmb3IoaiBpbiBzZXFfYWxvbmcoY2x1c3QuYXNzZXNzKSl7CiAgICBvdXRwdXQuc3RhdHNbaiwgaV0gPC0gdW5saXN0KGNsdXN0ZXIuc3RhdHMoZCA9IGRpc3QsIGNsdXN0ZXJpbmcgPSBjdXRyZWUodHJlZSwgayA9IGkpKVtjbHVzdC5hc3Nlc3NdKVtqXQogICAgCiAgfQogIAogIGZvcihkIGluIDE6aykgewogICAgY2x1c3Rlci5zaXplc1tkLCBpXSA8LSB1bmxpc3QoY2x1c3Rlci5zdGF0cyhkID0gZGlzdCwgY2x1c3RlcmluZyA9IGN1dHJlZSh0cmVlLCBrID0gaSkpW2NsdXN0LnNpemVdKVtkXQogICAgZGltKGNsdXN0ZXIuc2l6ZXNbZCwgaV0pIDwtIGMobGVuZ3RoKGNsdXN0ZXIuc2l6ZXNbaV0pLCAxKQogICAgY2x1c3Rlci5zaXplc1tkLCBpXQogICAgCiAgfQp9Cm91dHB1dC5zdGF0cy5kZiA8LSBkYXRhLmZyYW1lKG91dHB1dC5zdGF0cykKY2x1c3Rlci5zaXplcyA8LSBkYXRhLmZyYW1lKGNsdXN0ZXIuc2l6ZXMpCmNsdXN0ZXIuc2l6ZXNbaXMubmEoY2x1c3Rlci5zaXplcyldIDwtIDAKcm93cy5hbGwgPC0gYyhjbHVzdC5hc3Nlc3MsIHJvdy5jbHVzdCkKIyByb3duYW1lcyhvdXRwdXQuc3RhdHMuZGYpIDwtIGNsdXN0LmFzc2VzcwpvdXRwdXQgPC0gcmJpbmQob3V0cHV0LnN0YXRzLmRmLCBjbHVzdGVyLnNpemVzKVsgLC0xXQpjb2xuYW1lcyhvdXRwdXQpIDwtIHN0YXRzLm5hbWVzWzI6a10Kcm93bmFtZXMob3V0cHV0KSA8LSByb3dzLmFsbAppcy5udW0gPC0gc2FwcGx5KG91dHB1dCwgaXMubnVtZXJpYykKb3V0cHV0W2lzLm51bV0gPC0gbGFwcGx5KG91dHB1dFtpcy5udW1dLCByb3VuZCwgMikKb3V0cHV0Cn0KIyBJIGFtIGNhcHBpbmcgdGhlIG1heGltdW0gYW1vdXQgb2YgY2x1c3RlcnMgYnkgNwojIEkgd2FudCB0byBjaG9vc2UgYSByZWFzb25hYmxlIG51bWJlciwgYmFzZWQgb24gd2hpY2ggSSB3aWxsIGJlIGFibGUgdG8gc2VlIGJhc2ljIGRpZmZlcmVuY2VzIGJldHdlZW4gY3VzdG9tZXIgZ3JvdXBzIGFzIGEgcmVzdWx0CnN0YXRzLmRmLmRpdmlzaXZlIDwtIGNzdGF0cy50YWJsZShkaXN0YW5jZSwgZGl2LCA3KQpzdGF0cy5kZi5kaXZpc2l2ZQoKc3RhdHMuZGYuYWdnbCA8LWNzdGF0cy50YWJsZShkaXN0YW5jZSwgYWdnLCA3KSAjY29tcGxldGUgbGlua2FnZXMgbG9va3MgbGlrZSB0aGUgbW9zdCBiYWxhbmNlZCBhcHByb2FjaApzdGF0cy5kZi5hZ2dsCgojY29uZnVzaW9uTWF0cml4KHRyYWluX3NtYWxsLCApCmBgYApgYGB7cn0KbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KG1sdG9vbHMpCiNDcmltZV9jaGljYWdvX2R1bW15IDwtIG9uZV9ob3QoYXMuZGF0YS50YWJsZShDcmltZV9jaGljYWdvX2RlZl9jbHVzdCkpCiNuYXJjb3RpY3MgPC0gc3Vic2V0KG5hcmNvdGljcywgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCiNuYXJjb3RpY3NfdHIgPC0gc3Vic2V0KG5hcmNvdGljc190ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCm5hcmNvdGljc19jbHVzdGVyaW5nIDwtIHN1YnNldChuYXJjb3RpY3MsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCm5hcmNvdGljc19jbHVzdGVyaW5nX3RyIDwtIHN1YnNldChuYXJjb3RpY3NfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCgp0eXBlcyA8LSB1bmlxdWUoY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nJHByaW1hcnlfdHlwZSkKbmFyY290aWNzX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlIDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRwcmltYXJ5X3R5cGUsIHVuaXF1ZShjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckcHJpbWFyeV90eXBlKSkKbmFyY290aWNzX2NsdXN0ZXJpbmckYXJyZXN0IDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRhcnJlc3QsIHVuaXF1ZShjaGljYWdvX2NyaW1lX2NsdXN0ZXJpbmckYXJyZXN0KSkKI25hcmNvdGljc19jbHVzdGVyaW5nJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIG1hdGNoKGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZyRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKG5hcmNvdGljc19jbHVzdGVyaW5nJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKbmFyY290aWNzX2NsdXN0ZXJpbmckZGlzdHJpY3QgPC0gYXMubnVtZXJpYyhuYXJjb3RpY3NfY2x1c3RlcmluZyRkaXN0cmljdCkKdGVzdCA8LSBuYXJjb3RpY3NfY2x1c3RlcmluZwojTm9ybWFsaXphdGlvbiBvZiB2YXJpYWJsZXMKbGlicmFyeShSU05OUykKCnRyYWluX3NldCA8LSBuYXJjb3RpY3NfY2x1c3RlcmluZ190cgp0cmFpbl9zZXQkcHJpbWFyeV90eXBlIDwtIG1hdGNoKHRyYWluX3NldCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9zZXQkcHJpbWFyeV90eXBlKSkKdHJhaW5fc2V0JGFycmVzdCA8LSBtYXRjaCh0cmFpbl9zZXQkYXJyZXN0LCB1bmlxdWUodHJhaW5fc2V0JGFycmVzdCkpCiN0cmFpbl9zZXQkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gbWF0Y2godHJhaW5fc2V0JGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fc2V0JGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdHJhaW5fc2V0JGRpc3RyaWN0IDwtIGFzLm51bWVyaWModHJhaW5fc2V0JGRpc3RyaWN0KQoKI2luZGV4IDwtIHNhbXBsZShucm93KGNoaWNhZ29fY3JpbWVfY2x1c3RlcmluZ19jdXQpLCByb3VuZCgwLjc1Km5yb3coY2hpY2Fnb19jcmltZV9jbHVzdGVyaW5nX2N1dCkpKQojdHJhaW4gPC0gQ3JpbWVfY2hpY2Fnb19kZWZfY2x1c3RfY3V0W2luZGV4LF0gCiN0ZXN0IDwtIENyaW1lX2NoaWNhZ29fZGVmX2NsdXN0X2N1dFstaW5kZXgsXQp0cmFpbl9sYWJlbCA8LSB0cmFpbl9zZXRbLDFdCnRlc3RfbGFiZWwgPC0gdGVzdFssMV0KCiNPcHRpbXVtIG51bWJlciBvZiBjbHVzdGVycy4gRWxib3cgbWV0aG9kCiMgQWx0ZXJuYXRpdmUgdXNpbmcgZnZpeiBmdW5jdGlvbiBmb3IgRWxib3cgbWV0aG9kCmxpYnJhcnkoZmFjdG9leHRyYSkKbGlicmFyeShOYkNsdXN0KQpzZXQuc2VlZCgxMjMpCnRyYWluX3NtYWxsIDwtIHRyYWluX3NldFsxOjEwMDAsXQp0ZXN0X3NtYWxsIDwtIHRlc3RbMToxMDAsXQoKIyMgRGVuZG9ncmFtcwpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICAjZGF0YSBtYW5pcHVsYXRpb24gYW5kIHZpc3VhbGl6YXRpb24KbGlicmFyeShjbGFzcykgICAgICAgICAgIyB0byBjYWxsIGNsYXNzIHBhY2thZ2UgZm9yIGtOTgpsaWJyYXJ5KGNhcmV0KQpsaWJyYXJ5KGNsdXN0ZXIpCiMgRGl2aXNpdmUgSGllcmFyY2hpY2FsIENsdXN0ZXJpbmcgLSBkaWFuYQojIGNvbXB1dGUgZGl2aXNpdmUgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcKZGl2IDwtIGRpYW5hKHRyYWluX3NtYWxsKQpwbG90KGRpdiwgbWFpbiA9ICJEaXZpc2l2ZSIpCgpkaXN0YW5jZSA8LSBkaXN0KHRyYWluX3NtYWxsLG1ldGhvZCA9ICJldWNsaWRlYW4iKQphZ2cgPC0gaGNsdXN0KGRpc3RhbmNlLCBtZXRob2QgPSAiY29tcGxldGUiKQpwbG90KGFnZywKICAgICBtYWluID0gIkFnZ2xvbWVyYXRpdmUsIGNvbXBsZXRlIGxpbmthZ2VzIikKCmxpYnJhcnkoZnBjKQpjc3RhdHMudGFibGUgPC0gZnVuY3Rpb24oZGlzdCwgdHJlZSwgaykgewpjbHVzdC5hc3Nlc3MgPC0gYygiY2x1c3Rlci5udW1iZXIiLCJuIiwid2l0aGluLmNsdXN0ZXIuc3MiLCJhdmVyYWdlLndpdGhpbiIsImF2ZXJhZ2UuYmV0d2VlbiIsCiAgICAgICAgICAgICAgICAgICJ3Yi5yYXRpbyIsImR1bm4yIiwiYXZnLnNpbHdpZHRoIikKY2x1c3Quc2l6ZSA8LSBjKCJjbHVzdGVyLnNpemUiKQpzdGF0cy5uYW1lcyA8LSBjKCkKcm93LmNsdXN0IDwtIGMoKQpvdXRwdXQuc3RhdHMgPC0gbWF0cml4KG5jb2wgPSBrLCBucm93ID0gbGVuZ3RoKGNsdXN0LmFzc2VzcykpCmNsdXN0ZXIuc2l6ZXMgPC0gbWF0cml4KG5jb2wgPSBrLCBucm93ID0gaykKZm9yKGkgaW4gYygxOmspKXsKICByb3cuY2x1c3RbaV0gPC0gcGFzdGUoIkNsdXN0ZXItIiwgaSwgIiBzaXplIikKfQpmb3IoaSBpbiBjKDI6aykpewogIHN0YXRzLm5hbWVzW2ldIDwtIHBhc3RlKCJUZXN0IiwgaS0xKQogIAogIGZvcihqIGluIHNlcV9hbG9uZyhjbHVzdC5hc3Nlc3MpKXsKICAgIG91dHB1dC5zdGF0c1tqLCBpXSA8LSB1bmxpc3QoY2x1c3Rlci5zdGF0cyhkID0gZGlzdCwgY2x1c3RlcmluZyA9IGN1dHJlZSh0cmVlLCBrID0gaSkpW2NsdXN0LmFzc2Vzc10pW2pdCiAgICAKICB9CiAgCiAgZm9yKGQgaW4gMTprKSB7CiAgICBjbHVzdGVyLnNpemVzW2QsIGldIDwtIHVubGlzdChjbHVzdGVyLnN0YXRzKGQgPSBkaXN0LCBjbHVzdGVyaW5nID0gY3V0cmVlKHRyZWUsIGsgPSBpKSlbY2x1c3Quc2l6ZV0pW2RdCiAgICBkaW0oY2x1c3Rlci5zaXplc1tkLCBpXSkgPC0gYyhsZW5ndGgoY2x1c3Rlci5zaXplc1tpXSksIDEpCiAgICBjbHVzdGVyLnNpemVzW2QsIGldCiAgICAKICB9Cn0Kb3V0cHV0LnN0YXRzLmRmIDwtIGRhdGEuZnJhbWUob3V0cHV0LnN0YXRzKQpjbHVzdGVyLnNpemVzIDwtIGRhdGEuZnJhbWUoY2x1c3Rlci5zaXplcykKY2x1c3Rlci5zaXplc1tpcy5uYShjbHVzdGVyLnNpemVzKV0gPC0gMApyb3dzLmFsbCA8LSBjKGNsdXN0LmFzc2Vzcywgcm93LmNsdXN0KQojIHJvd25hbWVzKG91dHB1dC5zdGF0cy5kZikgPC0gY2x1c3QuYXNzZXNzCm91dHB1dCA8LSByYmluZChvdXRwdXQuc3RhdHMuZGYsIGNsdXN0ZXIuc2l6ZXMpWyAsLTFdCmNvbG5hbWVzKG91dHB1dCkgPC0gc3RhdHMubmFtZXNbMjprXQpyb3duYW1lcyhvdXRwdXQpIDwtIHJvd3MuYWxsCmlzLm51bSA8LSBzYXBwbHkob3V0cHV0LCBpcy5udW1lcmljKQpvdXRwdXRbaXMubnVtXSA8LSBsYXBwbHkob3V0cHV0W2lzLm51bV0sIHJvdW5kLCAyKQpvdXRwdXQKfQojIEkgYW0gY2FwcGluZyB0aGUgbWF4aW11bSBhbW91dCBvZiBjbHVzdGVycyBieSA3CiMgSSB3YW50IHRvIGNob29zZSBhIHJlYXNvbmFibGUgbnVtYmVyLCBiYXNlZCBvbiB3aGljaCBJIHdpbGwgYmUgYWJsZSB0byBzZWUgYmFzaWMgZGlmZmVyZW5jZXMgYmV0d2VlbiBjdXN0b21lciBncm91cHMgYXMgYSByZXN1bHQKc3RhdHMuZGYuZGl2aXNpdmUgPC0gY3N0YXRzLnRhYmxlKGRpc3RhbmNlLCBkaXYsIDcpCnN0YXRzLmRmLmRpdmlzaXZlCgpzdGF0cy5kZi5hZ2dsIDwtY3N0YXRzLnRhYmxlKGRpc3RhbmNlLCBhZ2csIDcpICNjb21wbGV0ZSBsaW5rYWdlcyBsb29rcyBsaWtlIHRoZSBtb3N0IGJhbGFuY2VkIGFwcHJvYWNoCnN0YXRzLmRmLmFnZ2wKCiNjb25mdXNpb25NYXRyaXgodHJhaW5fc21hbGwsICkKYGBgCgpgYGB7cn0KbGlicmFyeSgiZ2dwbG90MiIpCmxpYnJhcnkoInJlc2hhcGUyIikKbGlicmFyeSgicHVycnIiKQpsaWJyYXJ5KCJkcGx5ciIpCiMgbGV0J3Mgc3RhcnQgd2l0aCBhIGRlbmRyb2dyYW0KbGlicmFyeSgiZGVuZGV4dGVuZCIpCmRlbmRybyA8LSBhcy5kZW5kcm9ncmFtKGFnZykKZGVuZHJvLmNvbCA8LSBkZW5kcm8gJT4lCiAgc2V0KCJicmFuY2hlc19rX2NvbG9yIiwgayA9IDgsIHZhbHVlID0gICBjKCJkYXJrc2xhdGVncmF5IiwgImRhcmtzbGF0ZWdyYXk0IiwgImRhcmtzbGF0ZWdyYXkzIiwgImdvbGQzIiwgImRhcmtjeWFuIiwgImN5YW4zIiwgImdvbGQzIikpICU+JQogIHNldCgiYnJhbmNoZXNfbHdkIiwgMC42KSAlPiUKICBzZXQoImxhYmVsc19jb2xvcnMiLCAKICAgICAgdmFsdWUgPSBjKCJkYXJrc2xhdGVncmF5IikpICU+JSAKICBzZXQoImxhYmVsc19jZXgiLCAwLjUpCmdnZDEgPC0gYXMuZ2dkZW5kKGRlbmRyby5jb2wpCmdncGxvdChnZ2QxLCB0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkgKwogIGxhYnMoeCA9ICJOdW0uIG9ic2VydmF0aW9ucyIsIHkgPSAiSGVpZ2h0IiwgdGl0bGUgPSAiRGVuZHJvZ3JhbSwgayA9IDgiKQoKCgpgYGAKIyMgQXJib2xlcyBkZSBEZWNpc2lvbgpgYGB7cn0KIyMgYzUwCgpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KE1BU1MpICAgICAgICAjIGZvciBvYnRhaW5pbmcgZGF0YQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICMgZm9yIGRhdGEgcHJvY2Vzc2luZwpsaWJyYXJ5KHJwYXJ0KSAgICAgICMgZm9yIENBUlQgZGVjaXNpb24gdHJlZQpsaWJyYXJ5KHJwYXJ0LnBsb3QpICMgZm9yIHBsb3R0aW5nIENBUlQKbGlicmFyeShjYXJldCkgICAgICAjIGZvciBjb25mdXNpb24gbWF0cml4IGFuZCBtb3JlCmxpYnJhcnkocnNhbXBsZSkgICAgIyBmb3IgZGF0YSBzcGxpdHRpbmcKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KEM1MCkKCgojbGV2ZWxzKGNoaWNhZ29fY3JpbWUkbG9jYXRpb25fZGVzY3JpcHRpb24pWzFdID0gIk5vbmUiCiMjIENyZWF0aW5nIGEgdHJhaW5pbmcgYW5kIHRlc3QgZGF0YXNldHMKc2V0LnNlZWQoMTIzNCkKCmNoaWNhZ29fY3JpbWVfdHJlZXMgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0LCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKY2hpY2Fnb19jcmltZV90cmVlc190ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbixjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKbGlicmFyeShkcGx5cikKY2hpY2Fnb19jcmltZV90cmVlcyAlPiUgbXV0YXRlX2lmKGlzLmZhY3RvciwgYXMuY2hhcmFjdGVyKSAtPiBjaGljYWdvX2NyaW1lX3RyZWVzCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIgJT4lIG11dGF0ZV9pZihpcy5mYWN0b3IsIGFzLmNoYXJhY3RlcikgLT4gY2hpY2Fnb19jcmltZV90cmVlc190cgoKY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGUgPT0gIlJPQkJFUlkiXSA8LSAiUk9CIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiTkFSQ09USUNTIl0gPC0gIk5BUiIKY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlcyRwcmltYXJ5X3R5cGUgPT0gIkFTU0FVTFQiXSA8LSAiQVNTIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiV0VBUE9OUyBWSU9MQVRJT04iXSA8LSAiV1YiCmNoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlID09ICJDUklNSU5BTCBEQU1BR0UiXSA8LSAiQ0QiCmNoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXMkcHJpbWFyeV90eXBlID09ICJWSU9MRU5UIENSSU1FIl0gPC0gIlZDIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiREVDRVBUSVZFIFBSQUNUSUNFIl0gPC0gIkRQIgpjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzJHByaW1hcnlfdHlwZSA9PSAiVEhFRlQiXSA8LSAiVEgiCgpjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZSA9PSAiUk9CQkVSWSJdIDwtICJST0IiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJOQVJDT1RJQ1MiXSA8LSAiTkFSIgpjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZVtjaGljYWdvX2NyaW1lX3RyZWVzX3RyJHByaW1hcnlfdHlwZSA9PSAiQVNTQVVMVCJdIDwtICJBU1MiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJXRUFQT05TIFZJT0xBVElPTiJdIDwtICJXViIKY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGUgPT0gIkNSSU1JTkFMIERBTUFHRSJdIDwtICJDRCIKY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGVbY2hpY2Fnb19jcmltZV90cmVlc190ciRwcmltYXJ5X3R5cGUgPT0gIlZJT0xFTlQgQ1JJTUUiXSA8LSAiVkMiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJERUNFUFRJVkUgUFJBQ1RJQ0UiXSA8LSAiRFAiCmNoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlW2NoaWNhZ29fY3JpbWVfdHJlZXNfdHIkcHJpbWFyeV90eXBlID09ICJUSEVGVCJdIDwtICJUSCIKCiN0cmFpbl9jNTA8LSBjaGljYWdvX2NyaW1lX3RyZWVzX3RyCiN0ZXN0X2M1MDwtIGNoaWNhZ29fY3JpbWVfdHJlZXMKCmNyaW1lX3NwbGl0X2M1MDwtIGluaXRpYWxfc3BsaXQoc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSksIHByb3A9MC44KQp0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCnRlc3RfYzUwPC0gdGVzdGluZyhjcmltZV9zcGxpdF9jNTApCgojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGFycmVzdCwgdW5pcXVlKHRyYWluX2M1MCRhcnJlc3QpKQojdGVzdF9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModGVzdF9jNTAkYXJyZXN0LCB1bmlxdWUodGVzdF9jNTAkYXJyZXN0KSkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fYzUwJHByaW1hcnlfdHlwZSkpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpKQojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGFycmVzdCkKdGVzdF9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRhcnJlc3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCnRyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCnRlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5mYWN0b3IodGVzdF9jNTAkcHJpbWFyeV90eXBlKQoKCiNDcmVhdGluZyB0aGUgZGVjaXNpb24gdHJlZSBhbGdvcml0aG0gQzQuNSAKdHJlZV9yZXN1bHQgPC0gQzUuMChwcmltYXJ5X3R5cGUgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMikpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsc3VidHJlZT1OVUxMKQoKIyMgUFJFRElDVElPTgojUHJlZGljdGlvbiBvZiBuZXcgY2FzZXMgZnJvbSB0aGUgdGVzdCBkYXRhc2V0CnByZWRpY3Rpb25zIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0ZXN0X2M1MCwgdHlwZSA9ImNsYXNzIikKCiN0YWJsZShwcmVkaWN0aW9uPXByZWRpY3Rpb25zLCByZWFsPSBjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCiNjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkaWN0aW9ucyAhPSB0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJHByaW1hcnlfdHlwZSksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRyYWluIHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRfdHJhaW49PXRyYWluX2M1MCRwcmltYXJ5X3R5cGUpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCgoKYGBgCmBgYHtyfQojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMSkpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsZmFjbGVuPTEwLCBjbGlwLmZhY3M9VFJVRSxzdWJ0cmVlPU5VTEwsIHR3ZWFrPTEsIGRpZ2l0cz0yKQoKIyMgUFJFRElDVElPTgojUHJlZGljdGlvbiBvZiBuZXcgY2FzZXMgZnJvbSB0aGUgdGVzdCBkYXRhc2V0CnByZWRpY3Rpb25zIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0ZXN0X2M1MCwgdHlwZSA9ImNsYXNzIikKCiN0YWJsZShwcmVkaWN0aW9uPXByZWRpY3Rpb25zLCByZWFsPSBjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCiNjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkaWN0aW9ucyAhPSB0ZXN0X2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdGVzdCBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkaWN0aW9ucz09dGVzdF9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZGljdGlvbnMpKQoKcHJlZF90cmFpbiA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdHJhaW5fYzUwKQojY29uZnVzaW9uTWF0cml4KHByZWRfdHJhaW4sIGNyaW1lX3RyYWluJGRpc3RyaWN0KQojcHJlZF90cmFpbjwtcm91bmQocHJlZF90cmFpbikKI3RhYmxlKHByZWRpY3Rpb249cHJlZF90cmFpbiwgcmVhbD0gY3JpbWVfdHJhaW5fYzUwJGFycmVzdCkKCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZF90cmFpbiAhPSB0cmFpbl9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRyYWluIHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRfdHJhaW49PXRyYWluX2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkX3RyYWluKSkKYGBgCmBgYHtyfQojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoYXJyZXN0ICB+IC4sIGRhdGE9dHJhaW5fYzUwLCBjb250cm9sID0gQzUuMENvbnRyb2wobm9HbG9iYWxQcnVuaW5nID0gRkFMU0UsIENGPSAwLjkpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCnN1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LGZhY2xlbj0xMCwgY2xpcC5mYWNzPVRSVUUsc3VidHJlZT1OVUxMLCB0d2Vhaz0xLCBkaWdpdHM9MikKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkYXJyZXN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRhcnJlc3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZGljdGlvbnMpKQoKcHJlZF90cmFpbiA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdHJhaW5fYzUwKQojY29uZnVzaW9uTWF0cml4KHByZWRfdHJhaW4sIGNyaW1lX3RyYWluJGRpc3RyaWN0KQojcHJlZF90cmFpbjwtcm91bmQocHJlZF90cmFpbikKI3RhYmxlKHByZWRpY3Rpb249cHJlZF90cmFpbiwgcmVhbD0gY3JpbWVfdHJhaW5fYzUwJGFycmVzdCkKCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZF90cmFpbiAhPSB0cmFpbl9jNTAkYXJyZXN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkYXJyZXN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKCgpgYGB7cn0KI2xldmVscyhjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKVsxXSA9ICJOb25lIgojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCiNhc3NhdWx0IDwtIHN1YnNldChhc3NhdWx0LCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQojYXNzYXVsdF90ciA8LSBzdWJzZXQoYXNzYXVsdF90ciwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKCmFzc2F1bHRfdHIgPC0gc3Vic2V0KGFzc2F1bHRfdHIsIGRpc3RyaWN0PT0iMyIgfCBkaXN0cmljdCA9PSAiNCIgfCBkaXN0cmljdCA9PSAiNSIgfCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0ID09ICIxOCIgfCBkaXN0cmljdCA9PSAiOSIgfCBkaXN0cmljdD09IjEwIiB8IGRpc3RyaWN0ID09ICIyMiIgfCBkaXN0cmljdCA9PSAiMTUiICkKYXNzYXVsdCA8LSBzdWJzZXQoYXNzYXVsdCwgZGlzdHJpY3Q9PSIzIiB8IGRpc3RyaWN0ID09ICI0IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiNyIgfCBkaXN0cmljdD09IjgiIHwgZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3QgPT0gIjE4IiB8IGRpc3RyaWN0ID09ICI5IiB8IGRpc3RyaWN0PT0iMTAiIHwgZGlzdHJpY3QgPT0gIjIyIiB8IGRpc3RyaWN0ID09ICIxNSIgKQoKI3RyYWluX2M1MDwtIHN1YnNldChhc3NhdWx0X3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKI3Rlc3RfYzUwPC0gc3Vic2V0KGFzc2F1bHQsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoYXNzYXVsdF90ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpLCBwcm9wPTAuOCkKdHJhaW5fYzUwPC0gdHJhaW5pbmcoY3JpbWVfc3BsaXRfYzUwKQp0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGFycmVzdCkKdGVzdF9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRhcnJlc3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCiN0cmFpbl9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkcHJpbWFyeV90eXBlKQojdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCgoKI0NyZWF0aW5nIHRoZSBkZWNpc2lvbiB0cmVlIGFsZ29yaXRobSBDNC41IAp0cmVlX3Jlc3VsdCA8LSBDNS4wKGRpc3RyaWN0ICB+IC4sIGRhdGE9dHJhaW5fYzUwLCBjb250cm9sID0gQzUuMENvbnRyb2wobm9HbG9iYWxQcnVuaW5nID0gRkFMU0UsIENGPSAwLjAwMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCnN1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LHN1YnRyZWU9TlVMTCkKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRpY3Rpb25zKSkKCnByZWRfdHJhaW4gPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRyYWluX2M1MCkKI2NvbmZ1c2lvbk1hdHJpeChwcmVkX3RyYWluLCBjcmltZV90cmFpbiRkaXN0cmljdCkKI3ByZWRfdHJhaW48LXJvdW5kKHByZWRfdHJhaW4pCiN0YWJsZShwcmVkaWN0aW9uPXByZWRfdHJhaW4sIHJlYWw9IGNyaW1lX3RyYWluX2M1MCRhcnJlc3QpCgplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRfdHJhaW4gIT0gdHJhaW5fYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCmBgYApgYGB7cn0KI2xldmVscyhjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKVsxXSA9ICJOb25lIgojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCiNjcmltaW5hbF9kYW1hZ2UgPC0gc3Vic2V0KGNyaW1pbmFsX2RhbWFnZSwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI2NyaW1pbmFsX2RhbWFnZV90ciA8LSBzdWJzZXQoIGNyaW1pbmFsX2RhbWFnZV90ciwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKY3JpbWluYWxfZGFtYWdlX3RyIDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2VfdHIsIGRpc3RyaWN0PT0iMyIgfCBkaXN0cmljdCA9PSAiNCIgfCBkaXN0cmljdCA9PSAiNSIgfCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0ID09ICIxOCIgIHwgZGlzdHJpY3QgPT0gIjkiIHwgZGlzdHJpY3Q9PSIyMCIgfCBkaXN0cmljdCA9PSAiMjUiIHwgZGlzdHJpY3QgPT0gIjExIikKY3JpbWluYWxfZGFtYWdlIDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2UsIGRpc3RyaWN0PT0iMyIgfCBkaXN0cmljdCA9PSAiNCIgfCBkaXN0cmljdCA9PSAiNSIgfCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0ID09ICIxOCIgIHwgZGlzdHJpY3QgPT0gIjkiIHwgZGlzdHJpY3Q9PSIyMCIgfCBkaXN0cmljdCA9PSAiMjUiIHwgZGlzdHJpY3QgPT0gIjExIikKCnRyYWluX2M1MDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2VfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldChjcmltaW5hbF9kYW1hZ2UsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKI2NyaW1lX3NwbGl0X2M1MDwtIGluaXRpYWxfc3BsaXQoc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSksIHByb3A9MC44KQojdHJhaW5fYzUwPC0gdHJhaW5pbmcoY3JpbWVfc3BsaXRfYzUwKQojdGVzdF9jNTA8LSB0ZXN0aW5nKGNyaW1lX3NwbGl0X2M1MCkKCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQp0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGFycmVzdCwgdW5pcXVlKHRyYWluX2M1MCRhcnJlc3QpKQojdGVzdF9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModGVzdF9jNTAkYXJyZXN0LCB1bmlxdWUodGVzdF9jNTAkYXJyZXN0KSkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fYzUwJHByaW1hcnlfdHlwZSkpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpKQojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGFycmVzdCkKdGVzdF9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRhcnJlc3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5mYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCnRyYWluX2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodHJhaW5fYzUwJGRpc3RyaWN0KQp0ZXN0X2M1MCRkaXN0cmljdCA8LSBmYWN0b3IodGVzdF9jNTAkZGlzdHJpY3QpCiN0cmFpbl9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkcHJpbWFyeV90eXBlKQojdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDAxKSkgICNIaWdoZXIgQ0YgbGVzcyBwcnVubmluZwpzdW1tYXJ5KHRyZWVfcmVzdWx0KQojUGxvdHRpbmcgdGhlIHRyZWUKcGxvdCh0cmVlX3Jlc3VsdCxzdWJ0cmVlPU5VTEwpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKYGBge3J9CiNsZXZlbHMoY2hpY2Fnb19jcmltZSRsb2NhdGlvbl9kZXNjcmlwdGlvbilbMV0gPSAiTm9uZSIKIyMgQ3JlYXRpbmcgYSB0cmFpbmluZyBhbmQgdGVzdCBkYXRhc2V0cwpzZXQuc2VlZCgxMjM0KQojZGVjZXB0aXZlX3ByYWN0aWNlIDwtIHN1YnNldChkZWNlcHRpdmVfcHJhY3RpY2UsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiNkZWNlcHRpdmVfcHJhY3RpY2VfdHIgPC0gc3Vic2V0KGRlY2VwdGl2ZV9wcmFjdGljZV90ciwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKCmRlY2VwdGl2ZV9wcmFjdGljZV90ciA8LSBzdWJzZXQoZGVjZXB0aXZlX3ByYWN0aWNlX3RyLCBkaXN0cmljdD09IjE5IiB8IGRpc3RyaWN0ID09ICI0IiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdD09IjIiIHwgZGlzdHJpY3QgPT0gIjI0IiB8ZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3QgPT0gIjE4InwgZGlzdHJpY3QgPT0gIjIwIiAgfCBkaXN0cmljdCA9PSAiOSIgfCBkaXN0cmljdD09IjIxIiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdCA9PSAiMTEiICkKCmRlY2VwdGl2ZV9wcmFjdGljZSA8LSBzdWJzZXQoZGVjZXB0aXZlX3ByYWN0aWNlLCBkaXN0cmljdD09IjE5IiB8IGRpc3RyaWN0ID09ICI0IiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdD09IjIiIHwgZGlzdHJpY3QgPT0gIjI0IiB8ZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3QgPT0gIjE4InwgZGlzdHJpY3QgPT0gIjIwIiAgfCBkaXN0cmljdCA9PSAiOSIgfCBkaXN0cmljdD09IjIxIiB8IGRpc3RyaWN0ID09ICIyNSIgfCBkaXN0cmljdCA9PSAiMTEiICkKCiN0cmFpbl9jNTA8LSBzdWJzZXQoZGVjZXB0aXZlX3ByYWN0aWNlX3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKI3Rlc3RfYzUwPC0gc3Vic2V0KGRlY2VwdGl2ZV9wcmFjdGljZSwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpjcmltZV9zcGxpdF9jNTA8LSBpbml0aWFsX3NwbGl0KHN1YnNldChkZWNlcHRpdmVfcHJhY3RpY2VfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbixjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCnRyYWluX2M1MDwtIHRyYWluaW5nKGNyaW1lX3NwbGl0X2M1MCkKdGVzdF9jNTA8LSB0ZXN0aW5nKGNyaW1lX3NwbGl0X2M1MCkKCiN0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCiN0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pKQojdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3RyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRkaXN0cmljdCwgdW5pcXVlKHRyYWluX2M1MCRkaXN0cmljdCkpCiN0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGRpc3RyaWN0LCB1bmlxdWUodGVzdF9jNTAkZGlzdHJpY3QpKQp0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkYXJyZXN0KQp0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuNSkpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKI3N1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LHN1YnRyZWU9TlVMTCkKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRpY3Rpb25zKSkKCnByZWRfdHJhaW4gPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRyYWluX2M1MCkKI2NvbmZ1c2lvbk1hdHJpeChwcmVkX3RyYWluLCBjcmltZV90cmFpbiRkaXN0cmljdCkKI3ByZWRfdHJhaW48LXJvdW5kKHByZWRfdHJhaW4pCiN0YWJsZShwcmVkaWN0aW9uPXByZWRfdHJhaW4sIHJlYWw9IGNyaW1lX3RyYWluX2M1MCRhcnJlc3QpCgplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRfdHJhaW4gIT0gdHJhaW5fYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCmBgYApgYGB7cn0KI2xldmVscyhjaGljYWdvX2NyaW1lJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKVsxXSA9ICJOb25lIgojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCiNuYXJjb3RpY3MgPC0gc3Vic2V0KG5hcmNvdGljcywgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI25hcmNvdGljc190ciA8LSBzdWJzZXQobmFyY290aWNzX3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQpuYXJjb3RpY3NfdHIgPC0gc3Vic2V0KG5hcmNvdGljc190ciwgZGlzdHJpY3Q9PSIxMCIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjE1IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4IikKbmFyY290aWNzIDwtIHN1YnNldChuYXJjb3RpY3MsIGRpc3RyaWN0PT0iMTAiIHwgZGlzdHJpY3QgPT0gIjExIiB8IGRpc3RyaWN0ID09ICIxNSIgfCBkaXN0cmljdD09IjgiIHwgZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3Q9PSIxOCIpCgojdHJhaW5fYzUwPC0gc3Vic2V0KG5hcmNvdGljc190ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCiN0ZXN0X2M1MDwtIHN1YnNldChuYXJjb3RpY3MsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQoKY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQobmFyY290aWNzX3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24sY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSksIHByb3A9MC44KQp0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCnRlc3RfYzUwPC0gdGVzdGluZyhjcmltZV9zcGxpdF9jNTApCgojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IodGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCiN0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGFycmVzdCwgdW5pcXVlKHRyYWluX2M1MCRhcnJlc3QpKQojdGVzdF9jNTAkYXJyZXN0IDwtIGFzLm51bWVyaWModGVzdF9jNTAkYXJyZXN0LCB1bmlxdWUodGVzdF9jNTAkYXJyZXN0KSkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodHJhaW5fYzUwJHByaW1hcnlfdHlwZSkpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0ZXN0X2M1MCRwcmltYXJ5X3R5cGUpKQojdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3Rlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRhcnJlc3QpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCnN1bW1hcnkodHJlZV9yZXN1bHQpCiNQbG90dGluZyB0aGUgdHJlZQpwbG90KHRyZWVfcmVzdWx0LHN1YnRyZWU9TlVMTCkKCiMjIFBSRURJQ1RJT04KI1ByZWRpY3Rpb24gb2YgbmV3IGNhc2VzIGZyb20gdGhlIHRlc3QgZGF0YXNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdGVzdF9jNTAsIHR5cGUgPSJjbGFzcyIpCgojdGFibGUocHJlZGljdGlvbj1wcmVkaWN0aW9ucywgcmVhbD0gY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQojY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZGljdGlvbnMgIT0gdGVzdF9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRlc3Qgc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZGljdGlvbnM9PXRlc3RfYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRpY3Rpb25zKSkKCnByZWRfdHJhaW4gPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRyYWluX2M1MCkKI2NvbmZ1c2lvbk1hdHJpeChwcmVkX3RyYWluLCBjcmltZV90cmFpbiRkaXN0cmljdCkKI3ByZWRfdHJhaW48LXJvdW5kKHByZWRfdHJhaW4pCiN0YWJsZShwcmVkaWN0aW9uPXByZWRfdHJhaW4sIHJlYWw9IGNyaW1lX3RyYWluX2M1MCRhcnJlc3QpCgplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRfdHJhaW4gIT0gdHJhaW5fYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0cmFpbiBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkX3RyYWluPT10cmFpbl9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZF90cmFpbikpCmBgYApgYGB7cn0KIyMgQ3JlYXRpbmcgYSB0cmFpbmluZyBhbmQgdGVzdCBkYXRhc2V0cwpzZXQuc2VlZCgxMjM0KQojcm9iYmVyeSA8LSBzdWJzZXQocm9iYmVyeSwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3JvYmJlcnlfdHIgPC0gc3Vic2V0KHJvYmJlcnlfdHIsIHNlbGVjdD0tYyhsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnJvYmJlcnlfdHIgPC0gc3Vic2V0KHJvYmJlcnlfdHIsIGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjE1IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4InwgZGlzdHJpY3Q9PSI5IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCnJvYmJlcnkgPC0gc3Vic2V0KHJvYmJlcnksIGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjE1IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4InwgZGlzdHJpY3Q9PSI5IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCgojcm9iYmVyeSRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBnc3ViKCJQQVJLSU5HIExPVCIsIlBBUktJTkciLHJvYmJlcnkkbG9jYXRpb25fZGVzY3JpcHRpb24pCiNyb2JiZXJ5X3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIlBBUktJTkcgTE9UIiwiUEFSS0lORyIscm9iYmVyeV90ciRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3JvYmJlcnkkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gZ3N1YigiUEFSS0lOR0dBUkFHRShOT04uUkVTSUQuKSIsIlBBUktJTkciLHJvYmJlcnkkbG9jYXRpb25fZGVzY3JpcHRpb24pCiNyb2JiZXJ5X3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGdzdWIoIlBBUktJTkdHQVJBR0UoTk9OLlJFU0lELikiLCJQQVJLSU5HIixyb2JiZXJ5X3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQoKdHJhaW5fYzUwPC0gc3Vic2V0KHJvYmJlcnlfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldChyb2JiZXJ5LCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKCiNjcmltZV9zcGxpdF9jNTA8LSBpbml0aWFsX3NwbGl0KHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldF90ciwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpLCBwcm9wPTAuOCkKI3RyYWluX2M1MDwtIHRyYWluaW5nKGNyaW1lX3NwbGl0X2M1MCkKI3Rlc3RfYzUwPC0gdGVzdGluZyhjcmltZV9zcGxpdF9jNTApCgp0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQp0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gZmFjdG9yKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gZmFjdG9yKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQojdHJhaW5fYzUwJGFycmVzdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRhcnJlc3QsIHVuaXF1ZSh0cmFpbl9jNTAkYXJyZXN0KSkKI3Rlc3RfYzUwJGFycmVzdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGFycmVzdCwgdW5pcXVlKHRlc3RfYzUwJGFycmVzdCkpCiN0cmFpbl9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpKQojdGVzdF9jNTAkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWModGVzdF9jNTAkcHJpbWFyeV90eXBlLCB1bmlxdWUodGVzdF9jNTAkcHJpbWFyeV90eXBlKSkKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uLCB1bmlxdWUodHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3RyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRkaXN0cmljdCwgdW5pcXVlKHRyYWluX2M1MCRkaXN0cmljdCkpCiN0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGRpc3RyaWN0LCB1bmlxdWUodGVzdF9jNTAkZGlzdHJpY3QpKQp0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkYXJyZXN0KQp0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4uLCBkYXRhPXRyYWluX2M1MCwgY29udHJvbCA9IEM1LjBDb250cm9sKG5vR2xvYmFsUHJ1bmluZyA9IFRSVUUsIENGPSAwLjAwMDAwMSkpICAjSGlnaGVyIENGIGxlc3MgcHJ1bm5pbmcKc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsc3VidHJlZT1OVUxMKQoKIyMgUFJFRElDVElPTgojUHJlZGljdGlvbiBvZiBuZXcgY2FzZXMgZnJvbSB0aGUgdGVzdCBkYXRhc2V0CnByZWRpY3Rpb25zIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0ZXN0X2M1MCwgdHlwZSA9ImNsYXNzIikKCiN0YWJsZShwcmVkaWN0aW9uPXByZWRpY3Rpb25zLCByZWFsPSBjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUpCiNjcmltZV90ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkaWN0aW9ucyAhPSB0ZXN0X2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdGVzdCBzZXQgaXM6IiwgMTAwKmVycm9yX2NsYXNzaWZpY2F0aW9uLCAiJSIsCiAgICAgIHN1bShwcmVkaWN0aW9ucz09dGVzdF9jNTAkZGlzdHJpY3QpLAogICAgICAiY29ycmVjdCBjbGFzc2lmaWVkIGNhc2VzIGZyb20iLCBsZW5ndGgocHJlZGljdGlvbnMpKQoKcHJlZF90cmFpbiA8LSBwcmVkaWN0KHRyZWVfcmVzdWx0LCBuZXdkYXRhID0gdHJhaW5fYzUwKQojY29uZnVzaW9uTWF0cml4KHByZWRfdHJhaW4sIGNyaW1lX3RyYWluJGRpc3RyaWN0KQojcHJlZF90cmFpbjwtcm91bmQocHJlZF90cmFpbikKI3RhYmxlKHByZWRpY3Rpb249cHJlZF90cmFpbiwgcmVhbD0gY3JpbWVfdHJhaW5fYzUwJGFycmVzdCkKCmVycm9yX2NsYXNzaWZpY2F0aW9uIDwtIG1lYW4ocHJlZF90cmFpbiAhPSB0cmFpbl9jNTAkZGlzdHJpY3QpCgpwYXN0ZSgiVGhlIGNsYXNzaWZpY2F0aW9uIGVycm9yIGluIHRyYWluIHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRfdHJhaW49PXRyYWluX2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkX3RyYWluKSkKYGBgCmBgYHtyfQojIyBDcmVhdGluZyBhIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCnNldC5zZWVkKDEyMzQpCnRoZWZ0IDwtIHN1YnNldCh0aGVmdCwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdGhlZnRfdHIgPC0gc3Vic2V0KHRoZWZ0X3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQp0aGVmdF90ciA8LSBzdWJzZXQodGhlZnRfdHIsIGRpc3RyaWN0PT0iMTkiIHwgZGlzdHJpY3QgPT0gIjEiIHwgZGlzdHJpY3Q9PSIxOCJ8IGRpc3RyaWN0PT0iMjQiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IikKdGhlZnQgPC0gc3Vic2V0KHRoZWZ0LCBkaXN0cmljdD09IjE5IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgifCBkaXN0cmljdD09IjI0IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCgp0cmFpbl9jNTA8LSBzdWJzZXQodGhlZnRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldCh0aGVmdCwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgojY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCiN0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCiN0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRhcnJlc3QpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCiNzdW1tYXJ5KHRyZWVfcmVzdWx0KQojUGxvdHRpbmcgdGhlIHRyZWUKcGxvdCh0cmVlX3Jlc3VsdCxzdWJ0cmVlPU5VTEwpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKYGBge3J9CnNldC5zZWVkKDEyMzQpCiN2aW9sZW50X2NyaW1lIDwtIHN1YnNldCh2aW9sZW50X2NyaW1lLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQojdmlvbGVudF90cl9jcmltZSA8LSBzdWJzZXQodmlvbGVudF90cl9jcmltZSwgc2VsZWN0PS1jKGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKdmlvbGVudF90cl9jcmltZSA8LSBzdWJzZXQodmlvbGVudF90cl9jcmltZSwgZGlzdHJpY3Q9PSI2IiB8IGRpc3RyaWN0ID09ICIxMSIgfCBkaXN0cmljdCA9PSAiMTUiIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgifCBkaXN0cmljdD09IjkiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IiB8IGRpc3RyaWN0ID09ICIxOSJ8IGRpc3RyaWN0ID09ICIyMCIgIHwgZGlzdHJpY3QgPT0gIjEwIiB8IGRpc3RyaWN0PT0iMjEiIHwgZGlzdHJpY3QgPT0gIjI1IiB8IGRpc3RyaWN0ID09ICIyIikKdmlvbGVudF9jcmltZSA8LSBzdWJzZXQodmlvbGVudF9jcmltZSwgZGlzdHJpY3Q9PSI2IiB8IGRpc3RyaWN0ID09ICIxMSIgfCBkaXN0cmljdCA9PSAiMTUiIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgifCBkaXN0cmljdD09IjkiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IiB8IGRpc3RyaWN0ID09ICIxOSJ8IGRpc3RyaWN0ID09ICIyMCIgIHwgZGlzdHJpY3QgPT0gIjEwIiB8IGRpc3RyaWN0PT0iMjEiIHwgZGlzdHJpY3QgPT0gIjI1IiB8IGRpc3RyaWN0ID09ICIyIikKCnRyYWluX2M1MDwtIHN1YnNldCh2aW9sZW50X3RyX2NyaW1lLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkZXNjcmlwdGlvbixkYXksbW9udGgsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKdGVzdF9jNTA8LSBzdWJzZXQodmlvbGVudF9jcmltZSwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgojY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCiN0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCiN0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCiN0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pKQojdGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKSkKI3RyYWluX2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRkaXN0cmljdCwgdW5pcXVlKHRyYWluX2M1MCRkaXN0cmljdCkpCiN0ZXN0X2M1MCRkaXN0cmljdCA8LSBhcy5udW1lcmljKHRlc3RfYzUwJGRpc3RyaWN0LCB1bmlxdWUodGVzdF9jNTAkZGlzdHJpY3QpKQp0cmFpbl9jNTAkYXJyZXN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkYXJyZXN0KQp0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIHRyaWFscyA9IDEwLGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDAwMDAxKSkgICNIaWdoZXIgQ0YgbGVzcyBwcnVubmluZwojc3VtbWFyeSh0cmVlX3Jlc3VsdCkKI1Bsb3R0aW5nIHRoZSB0cmVlCnBsb3QodHJlZV9yZXN1bHQsc3VidHJlZT1OVUxMLHRyaWFsPTkpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQojd2VhcG9uc192aW9sYXRpb24gPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQojd2VhcG9uc192aW9sYXRpb25fdHIgPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uX3RyLCBzZWxlY3Q9LWMobG9jYXRpb25fZGVzY3JpcHRpb24pKQp3ZWFwb25zX3Zpb2xhdGlvbl90ciA8LSBzdWJzZXQod2VhcG9uc192aW9sYXRpb25fdHIsIGRpc3RyaWN0PT0iNiIgfCBkaXN0cmljdCA9PSAiMTEiIHwgZGlzdHJpY3QgPT0gIjciIHwgZGlzdHJpY3Q9PSI4IiB8IGRpc3RyaWN0ID09ICIxIiB8IGRpc3RyaWN0PT0iMTgiIHwgZGlzdHJpY3QgPT0gIjUiIHwgZGlzdHJpY3Q9PSI0IikKd2VhcG9uc192aW9sYXRpb24gPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uLCBkaXN0cmljdD09IjYiIHwgZGlzdHJpY3QgPT0gIjExIiB8IGRpc3RyaWN0ID09ICI3IiB8IGRpc3RyaWN0PT0iOCIgfCBkaXN0cmljdCA9PSAiMSIgfCBkaXN0cmljdD09IjE4IiB8IGRpc3RyaWN0ID09ICI1IiB8IGRpc3RyaWN0PT0iNCIpCgp0cmFpbl9jNTA8LSBzdWJzZXQod2VhcG9uc192aW9sYXRpb25fdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKQp0ZXN0X2M1MDwtIHN1YnNldCh3ZWFwb25zX3Zpb2xhdGlvbiwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGVzY3JpcHRpb24sZGF5LG1vbnRoLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgojY3JpbWVfc3BsaXRfYzUwPC0gaW5pdGlhbF9zcGxpdChzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixibG9jayx3YXJkLGRlc2NyaXB0aW9uLGRheSxtb250aCxsYXRpdHVkZSxsb25naXR1ZGUpKSwgcHJvcD0wLjgpCiN0cmFpbl9jNTA8LSB0cmFpbmluZyhjcmltZV9zcGxpdF9jNTApCiN0ZXN0X2M1MDwtIHRlc3RpbmcoY3JpbWVfc3BsaXRfYzUwKQoKdHJhaW5fYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24pCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkYXJyZXN0LCB1bmlxdWUodHJhaW5fYzUwJGFycmVzdCkpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRhcnJlc3QsIHVuaXF1ZSh0ZXN0X2M1MCRhcnJlc3QpKQojdHJhaW5fYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUsIHVuaXF1ZSh0cmFpbl9jNTAkcHJpbWFyeV90eXBlKSkKI3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKHRlc3RfYzUwJHByaW1hcnlfdHlwZSwgdW5pcXVlKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkpCnRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbiwgdW5pcXVlKHRyYWluX2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCnRlc3RfYzUwJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWModGVzdF9jNTAkbG9jYXRpb25fZGVzY3JpcHRpb24sIHVuaXF1ZSh0ZXN0X2M1MCRsb2NhdGlvbl9kZXNjcmlwdGlvbikpCiN0cmFpbl9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0cmFpbl9jNTAkZGlzdHJpY3QsIHVuaXF1ZSh0cmFpbl9jNTAkZGlzdHJpY3QpKQojdGVzdF9jNTAkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyh0ZXN0X2M1MCRkaXN0cmljdCwgdW5pcXVlKHRlc3RfYzUwJGRpc3RyaWN0KSkKI3RyYWluX2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRhcnJlc3QpCiN0ZXN0X2M1MCRhcnJlc3QgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJGFycmVzdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGFzLmZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKdHJhaW5fYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0cmFpbl9jNTAkZGlzdHJpY3QpCnRlc3RfYzUwJGRpc3RyaWN0IDwtIGZhY3Rvcih0ZXN0X2M1MCRkaXN0cmljdCkKI3RyYWluX2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRyYWluX2M1MCRwcmltYXJ5X3R5cGUpCiN0ZXN0X2M1MCRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKHRlc3RfYzUwJHByaW1hcnlfdHlwZSkKCgojQ3JlYXRpbmcgdGhlIGRlY2lzaW9uIHRyZWUgYWxnb3JpdGhtIEM0LjUgCnRyZWVfcmVzdWx0IDwtIEM1LjAoZGlzdHJpY3QgIH4gLiwgZGF0YT10cmFpbl9jNTAsIGNvbnRyb2wgPSBDNS4wQ29udHJvbChub0dsb2JhbFBydW5pbmcgPSBGQUxTRSwgQ0Y9IDAuMDEpKSAgI0hpZ2hlciBDRiBsZXNzIHBydW5uaW5nCiNzdW1tYXJ5KHRyZWVfcmVzdWx0KQojUGxvdHRpbmcgdGhlIHRyZWUKcGxvdCh0cmVlX3Jlc3VsdCxzdWJ0cmVlPU5VTEwpCgojIyBQUkVESUNUSU9OCiNQcmVkaWN0aW9uIG9mIG5ldyBjYXNlcyBmcm9tIHRoZSB0ZXN0IGRhdGFzZXQKcHJlZGljdGlvbnMgPC0gcHJlZGljdCh0cmVlX3Jlc3VsdCwgbmV3ZGF0YSA9IHRlc3RfYzUwLCB0eXBlID0iY2xhc3MiKQoKI3RhYmxlKHByZWRpY3Rpb249cHJlZGljdGlvbnMsIHJlYWw9IGNyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSkKI2NyaW1lX3Rlc3RfYzUwJHByaW1hcnlfdHlwZSA8LSBmYWN0b3IoY3JpbWVfdGVzdF9jNTAkcHJpbWFyeV90eXBlKQplcnJvcl9jbGFzc2lmaWNhdGlvbiA8LSBtZWFuKHByZWRpY3Rpb25zICE9IHRlc3RfYzUwJGRpc3RyaWN0KQoKcGFzdGUoIlRoZSBjbGFzc2lmaWNhdGlvbiBlcnJvciBpbiB0ZXN0IHNldCBpczoiLCAxMDAqZXJyb3JfY2xhc3NpZmljYXRpb24sICIlIiwKICAgICAgc3VtKHByZWRpY3Rpb25zPT10ZXN0X2M1MCRkaXN0cmljdCksCiAgICAgICJjb3JyZWN0IGNsYXNzaWZpZWQgY2FzZXMgZnJvbSIsIGxlbmd0aChwcmVkaWN0aW9ucykpCgpwcmVkX3RyYWluIDwtIHByZWRpY3QodHJlZV9yZXN1bHQsIG5ld2RhdGEgPSB0cmFpbl9jNTApCiNjb25mdXNpb25NYXRyaXgocHJlZF90cmFpbiwgY3JpbWVfdHJhaW4kZGlzdHJpY3QpCiNwcmVkX3RyYWluPC1yb3VuZChwcmVkX3RyYWluKQojdGFibGUocHJlZGljdGlvbj1wcmVkX3RyYWluLCByZWFsPSBjcmltZV90cmFpbl9jNTAkYXJyZXN0KQoKZXJyb3JfY2xhc3NpZmljYXRpb24gPC0gbWVhbihwcmVkX3RyYWluICE9IHRyYWluX2M1MCRkaXN0cmljdCkKCnBhc3RlKCJUaGUgY2xhc3NpZmljYXRpb24gZXJyb3IgaW4gdHJhaW4gc2V0IGlzOiIsIDEwMCplcnJvcl9jbGFzc2lmaWNhdGlvbiwgIiUiLAogICAgICBzdW0ocHJlZF90cmFpbj09dHJhaW5fYzUwJGRpc3RyaWN0KSwKICAgICAgImNvcnJlY3QgY2xhc3NpZmllZCBjYXNlcyBmcm9tIiwgbGVuZ3RoKHByZWRfdHJhaW4pKQpgYGAKYGBge3J9CmxpYnJhcnkoTUFTUykgICAgICAgIyBmb3Igb2J0YWluaW5nIGRhdGEKbGlicmFyeSh0aWR5dmVyc2UpICAjIGZvciBkYXRhIHByb2Nlc3NpbmcKbGlicmFyeShycGFydCkgICAgICAjIGZvciBDQVJUIGRlY2lzaW9uIHRyZWUKbGlicmFyeShycGFydC5wbG90KSAjIGZvciBwbG90dGluZyBDQVJUCmxpYnJhcnkoY2FyZXQpICAgICAgIyBmb3IgY29uZnVzaW9uIG1hdHJpeCBhbmQgbW9yZQpsaWJyYXJ5KHJzYW1wbGUpICAgICMgZm9yIGRhdGEgc3BsaXR0aW5nCmxpYnJhcnkocmFuZG9tRm9yZXN0KSAgIyBGb3IgYmFnZ2luZyBhbmQgcmFuZG9tZm9yZXN0CmxpYnJhcnkoZ2dwdWJyKQoKIyMgU29sbyBzZSBwdWVkZW4gdGVuZXIgNTMgdmFsb3JlcyBjYXRlZ29yaWNvcyB1bmljb3MgZGlmZXJlbnRlcy4gUG9yIGVzdGEgcmF6b24gaGF5IHF1ZSBoYWNlciByZWdyZXNpb24gY29uIHNvbG8gZXN0YXMgdmFyaWFibGVzLgpjaGljYWdvX2NyaW1lX2Vuc2VtYmxlIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLGRlc2NyaXB0aW9uLGxvY2F0aW9uX2Rlc2NyaXB0aW9uLHdhcmQsbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhjYXNlX251bWJlcixsb2NhdGlvbl9kZXNjcmlwdGlvbixkZXNjcmlwdGlvbixibG9jayx3YXJkLGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJHByaW1hcnlfdHlwZSA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfZW5zZW1ibGUkcHJpbWFyeV90eXBlKQpjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJGFycmVzdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRhcnJlc3QpCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGUkYXJyZXN0IDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRhcnJlc3QpCiNjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJHByaW1hcnlfdHlwZSA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRwcmltYXJ5X3R5cGUpCiNjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJGRlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRkZXNjcmlwdGlvbiA8LSBmYWN0b3IoY2hpY2Fnb19jcmltZV9lbnNlbWJsZSRkZXNjcmlwdGlvbikKI2NoaWNhZ29fY3JpbWVfZW5zZW1ibGUkcHJpbWFyeV90eXBlIDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlJHByaW1hcnlfdHlwZSkKCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciRwcmltYXJ5X3R5cGUpCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkYXJyZXN0IDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGFycmVzdCkKY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciRhcnJlc3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGFycmVzdCkKI2NoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkcHJpbWFyeV90eXBlIDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJHByaW1hcnlfdHlwZSkKI2NoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkZGVzY3JpcHRpb24pCiNjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGRlc2NyaXB0aW9uIDwtIGZhY3RvcihjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyJGRlc2NyaXB0aW9uKQojY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciRwcmltYXJ5X3R5cGUgPC0gZmFjdG9yKGNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIkcHJpbWFyeV90eXBlKQoKY2hpY2Fnb19jcmltZV9lbnNlbWJsZV90ciA8LSBuYS5vbWl0KGNoaWNhZ29fY3JpbWVfZW5zZW1ibGVfdHIpCmNoaWNhZ29fY3JpbWVfZW5zZW1ibGUgPC0gbmEub21pdChjaGljYWdvX2NyaW1lX2Vuc2VtYmxlKQoKI1JGX3NwbGl0PC0gaW5pdGlhbF9zcGxpdChjaGljYWdvX2NyaW1lLCBwcm9wPTAuOCkKUkZfdHJhaW48LSBjaGljYWdvX2NyaW1lX2Vuc2VtYmxlX3RyWzE6MTAwMDAsXQpSRl90ZXN0PC0gY2hpY2Fnb19jcmltZV9lbnNlbWJsZVsxOjEwMDAsXQoKYmFnZ2luZ19tb2RlbDwtIHJhbmRvbUZvcmVzdChmb3JtdWxhPXByaW1hcnlfdHlwZSAgfiAuLCBkYXRhPVJGX3RyYWluLG10cnk9NCkgICM0IGZyb20gMTMgcHJlZGljdG9ycyB3aWxsIGJlIHNlbGVjdGVkCgojUmVzdWx0IG9mIHJhbmRvbSBmb3Jlc3QgbW9kZWwKcHJpbnQoYmFnZ2luZ19tb2RlbCkKCmBgYAojIyBSRURFUyBORVVST05BTEVTCmBgYHtyfQojIyBSRURFUwpjaGljYWdvX2NyaW1lX25uIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGNhc2VfbnVtYmVyLGJsb2NrLHdhcmQsZGF5LGxhdGl0dWRlLGxvbmdpdHVkZSkpCmNoaWNhZ29fY3JpbWVfbm5fdHIgPC0gc3Vic2V0KGNoaWNhZ29fY3JpbWVfc3Vic2V0X3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssd2FyZCxkYXksbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKCmxpYnJhcnkoa29ob25lbikgIyBmb3IgYnVpbGRpbmcgdGhlIFNPTSBtYXAKbGlicmFyeShjYXJldCkgICAgICNmb3IgY29uZnVzaW9uIG1hdHJpeAoKI0V4dHJhY3RpbmcgdGFyZ2V0IHZhcmlhYmxlCnRhcmdldF90cmFpbiA8LSBjaGljYWdvX2NyaW1lX25uX3RyJHByaW1hcnlfdHlwZQpjaGljYWdvX2NyaW1lX25uX3RyIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX25uX3RyLCBzZWxlY3Q9LWMocHJpbWFyeV90eXBlKSkKCmNoaWNhZ29fY3JpbWVfbm5fdHIkYXJyZXN0IDwtIGFzLmZhY3RvcihjaGljYWdvX2NyaW1lX25uX3RyJGFycmVzdCkKY2hpY2Fnb19jcmltZV9ubl90ciRhcnJlc3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyJGFycmVzdCkKI2NoaWNhZ29fY3JpbWUkcHJpbWFyeV90eXBlIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUpCmNoaWNhZ29fY3JpbWVfbm5fdHIkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyJGRpc3RyaWN0KQojY2hpY2Fnb19jcmltZV9ubl90ciRkaXN0cmljdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90ciRkaXN0cmljdCkKY2hpY2Fnb19jcmltZV9ubl90ciRkZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90ciRkZXNjcmlwdGlvbikKY2hpY2Fnb19jcmltZV9ubl90ciRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfbm5fdHIkZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkbG9jYXRpb25fZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIkbG9jYXRpb25fZGVzY3JpcHRpb24gPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX25uX3RyJG1vbnRoIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90ciRtb250aCkKI2NoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGggPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGgpCgojU2NhbGluZyBvcmlnaW5hbCBkYXRhCnNldC5zZWVkKDcpCgoKIyBjcmVhdGlvbiBvZiB0cmFpbmluZyBhbmQgdGVzdCBkYXRhc2V0cwppbmRleCA8LSBzYW1wbGUobnJvdyhjaGljYWdvX2NyaW1lX25uX3RyKSwgcm91bmQoMC43NSpucm93KGNoaWNhZ29fY3JpbWVfbm5fdHIpKSkKdHJhaW4gPC0gY2hpY2Fnb19jcmltZV9ubl90cltpbmRleCxdCnRlc3QgPC0gY2hpY2Fnb19jcmltZV9ubl90clstaW5kZXgsXQoKdHJhaW4gPC0gYXMubWF0cml4KHRyYWluKQp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKdHJhaW5fbGFiZWw8LXRhcmdldF90cmFpbltpbmRleF0KdGVzdF9sYWJlbDwtdGFyZ2V0X3RyYWluWy1pbmRleF0KCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09OCwgeWRpbT04LCB0b3BvPSJoZXhhZ29uYWwiKQoKI3RyYWluaW5nIHRoZSBtYXAKY3JpbWUuc29tIDwtIHNvbSh0cmFpblsxOjEwMDAwMCxdLCBncmlkPXNvbV9ncmlkLCAKICAgICAgICAgICAgICAgcmxlbj0xMDAsIGFscGhhPWMoMC4wNSwgMC4wMSksIAogICAgICAgICAgICAgICByYWRpdXM9IDIsIGtlZXAuZGF0YT1UKQoKIyBOYW1lcyBvZiB0aGUgdmFyaWFibGVzIHVzZWQKY29sbmFtZXModHJhaW4pCgojIG1haW4gY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBtYXAKc3VtbWFyeShjcmltZS5zb20pCgojU2hvd2luZyB0aGUgdHJhaW5pbmcgcHJvY2VzcwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY2hhbmdlcyIpCgojbm9kZSBjb3VudHMKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvdW50cyIsIG1haW49IkV4YW1wbGVzIHBlciBOZXVyb24iKQoKI0NvZGVzL1dlaWdodCB2ZWN0b3JzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb2RlcyIsIG1haW49IlBhdHRlcm5zIERpc2NvdmVyZWQiKQoKY29vbEJsdWVIT3RSZWQ8LWZ1bmN0aW9uKG4sIGFscGhhPTEpe3JhaW5ib3cobixlbmQ9NC82LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGE9YWxwaGEpW246MV19CnBhcihtZnJvdz1jKDIsMykpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDFdLAogICAgIG1haW49Y29sbmFtZXMoZ2V0Q29kZXMoY3JpbWUuc29tLCAxKSlbMV0sCiAgICAgcGFsZXR0ZS5uYW1lPWNvb2xCbHVlSE90UmVkKQpwbG90KGNyaW1lLnNvbSwgdHlwZT0icHJvcGVydHkiLCBwcm9wZXJ0eT1nZXRDb2RlcyhjcmltZS5zb20sIDEpWywyXSwKICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzJdLAogICAgIHBhbGV0dGUubmFtZT1jb29sQmx1ZUhPdFJlZCkKcGxvdChjcmltZS5zb20sIHR5cGU9InByb3BlcnR5IiwgcHJvcGVydHk9Z2V0Q29kZXMoY3JpbWUuc29tLCAxKVssM10sCiAgICAgbWFpbj1jb2xuYW1lcyhnZXRDb2RlcyhjcmltZS5zb20sIDEpKVszXSwKICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIT3RSZWQpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDRdLAogICAgIG1haW49Y29sbmFtZXMoZ2V0Q29kZXMoY3JpbWUuc29tLCAxKSlbNF0sCiAgICAgcGFsZXR0ZS5uYW1lPWNvb2xCbHVlSE90UmVkKQpwbG90KGNyaW1lLnNvbSwgdHlwZT0icHJvcGVydHkiLCBwcm9wZXJ0eT1nZXRDb2RlcyhjcmltZS5zb20sIDEpWyw1XSwKICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzVdLAogICAgIHBhbGV0dGUubmFtZT1jb29sQmx1ZUhPdFJlZCkKI3Bsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDZdLAojICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzZdLAojICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIT3RSZWQpCgojIEFsdGVybmF0aXZlIGVhc2llcgpjb29sQmx1ZUhvdFJlZDwtZnVuY3Rpb24obiwgYWxwaGE9MSl7cmFpbmJvdyhuLGVuZD00LzYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT1hbHBoYSlbbjoxXX0KCnBhcihtZnJvdz1jKDUsMykpCmZvciAoaiBpbiAxOm5jb2wodHJhaW4pKSB7CnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWNyaW1lLnNvbSRjb2Rlc1tbMV1dWyxqXSwKICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIb3RSZWQsCiAgICAgbWFpbj1jb2xuYW1lcyh0cmFpbilbal0sIGNleD0wLjUpCn0KCiNzb20ucHJlZGljdGlvbiA8LSBwcmVkaWN0KGNyaW1lLnNvbSwgdGVzdCkKYGBgCmBgYHtyfQojQ2x1c3RlcmluZyBwYXR0ZXJucyBpbiB0aGUgbWFwCmdyb3VwczwtOAojQXBwbHlpbmcgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgZm9yIGdyb3VwaW5nIHBhdHRlcm5zCmNyaW1lLmhjPWN1dHJlZShoY2x1c3QoZGlzdChjcmltZS5zb20kY29kZXNbWzFdXSkpLCBncm91cHMpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb2RlcyIsIGJnY29sID0gcmFpbmJvdyhncm91cHMpW2NyaW1lLmhjXSwKICAgICBtYWluPSJjbHVzdGVyaW5nIHRoZSBwYXR0ZXJucyBkaXNjb3ZlcmVkIikKYWRkLmNsdXN0ZXIuYm91bmRhcmllcyhjcmltZS5zb20sY3JpbWUuaGMpCmBgYApgYGB7cn0KCiNTY2FsaW5nIG9yaWdpbmFsIGRhdGEKc2V0LnNlZWQoNykKCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09OCwgeWRpbT04LCB0b3BvPSJoZXhhZ29uYWwiKQpzZXQuc2VlZCg3KQprb2htYXAgPC0geHlmKHRyYWluWzE6MTAwMDAwLF0sIHRyYWluX2xhYmVsWzE6MTAwMDAwXSwKICAgICAgICAgICAgICBncmlkPXNvbV9ncmlkLCAKICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgcmFkaXVzPSAyLCBrZWVwLmRhdGE9VCkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3Qoa29obWFwLCB0eXBlPSJjaGFuZ2VzIikKCiNTaG93aW5nIGRpc3RyaWJ1dGlvbiBvZiB3aW5lIGxhYmVscyBpbiBuZXVyb25zCnBsb3Qoa29obWFwLCB0eXBlPSJjb2RlcyIsICBjb2RlUmVuZGVyaW5nID0gImxpbmVzIiwgc2hhcGU9InN0cmFpZ2h0IiwKICAgICBtYWluPWMoIkNyaW1lIikpCgpwbG90KGtvaG1hcCwgdHlwZT0iY29kZXMiLCAgY29kZVJlbmRlcmluZyA9ICJsaW5lcyIsIHNoYXBlPSJzdHJhaWdodCIsCiAgICAgbWFpbj1jKCIgcGF0dGVybnMiKSkKCiMgUGxvdHRpbmcgY2xhc3NlcyBpbiBuZXVyb25zCnBsb3Qoa29obWFwLCB0eXBlPSJtYXBwaW5nIiwgbGFiZWxzPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsCiAgICAgY29sPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsIHBjaD00LCBtYWluPSJNYXAgb2YgY2xhc3NlcyIsIHBhbGV0dGUubmFtZSA9IHRlcnJhaW4uY29sb3JzKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRyYWluaW5nIGRhdGEKcHJpbnQoIlRSQUlOSU5HIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdF90cjwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRyYWluLCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZV90cjwtdGFibGUodHJhaW5fbGFiZWwsa29obWFwLnByZWRpY3RfdHIkcHJlZGljdGlvbnNbWzJdXSkKY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25fdGFibGVfdHIpCgojUHJlZGljdGlvbiB1c2luZyB0aGUgdGVzdCBkYXRhCnByaW50KCJURVNUIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdDwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRlc3QsIHdoYXRtYXAgPSAxKQpwcmVkaWN0aW9uX3RhYmxlPC10YWJsZSh0ZXN0X2xhYmVsLGtvaG1hcC5wcmVkaWN0JHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlKQpgYGAKYGBge3J9CiMjIFJFREVTCmNoaWNhZ29fY3JpbWVfbm4yIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX3N1YnNldCwgc2VsZWN0PS1jKGRlc2NyaXB0aW9uLGNhc2VfbnVtYmVyLGJsb2NrLGRheSxsYXRpdHVkZSxsb25naXR1ZGUpKQpjaGljYWdvX2NyaW1lX25uX3RyMiA8LSBzdWJzZXQoY2hpY2Fnb19jcmltZV9zdWJzZXRfdHIsIHNlbGVjdD0tYyhkZXNjcmlwdGlvbixjYXNlX251bWJlcixibG9jayxkYXksbGF0aXR1ZGUsbG9uZ2l0dWRlKSkKCmxpYnJhcnkoa29ob25lbikgIyBmb3IgYnVpbGRpbmcgdGhlIFNPTSBtYXAKbGlicmFyeShjYXJldCkgICAgICNmb3IgY29uZnVzaW9uIG1hdHJpeAoKI0V4dHJhY3RpbmcgdGFyZ2V0IHZhcmlhYmxlCnRhcmdldF90cmFpbjIgPC0gY2hpY2Fnb19jcmltZV9ubl90cjIkcHJpbWFyeV90eXBlCmNoaWNhZ29fY3JpbWVfbm5fdHIyIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX25uX3RyMiwgc2VsZWN0PS1jKHByaW1hcnlfdHlwZSkpCgp0YXJnZXRfdGVzdDIgPC0gY2hpY2Fnb19jcmltZV9ubjIkcHJpbWFyeV90eXBlCmNoaWNhZ29fY3JpbWVfbm4yIDwtIHN1YnNldChjaGljYWdvX2NyaW1lX25uMiwgc2VsZWN0PS1jKHByaW1hcnlfdHlwZSkpCgpjaGljYWdvX2NyaW1lX25uX3RyMiRhcnJlc3QgPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIyJGFycmVzdCkKY2hpY2Fnb19jcmltZV9ubl90cjIkYXJyZXN0IDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90cjIkYXJyZXN0KQojY2hpY2Fnb19jcmltZSRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lJHByaW1hcnlfdHlwZSkKY2hpY2Fnb19jcmltZV9ubl90cjIkZGlzdHJpY3QgPC0gYXMubnVtZXJpYyhjaGljYWdvX2NyaW1lX25uX3RyMiRkaXN0cmljdCkKI2NoaWNhZ29fY3JpbWVfbm5fdHIkZGlzdHJpY3QgPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkZGlzdHJpY3QpCiNjaGljYWdvX2NyaW1lX25uX3RyMiRkZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90cjIkZGVzY3JpcHRpb24pCiNjaGljYWdvX2NyaW1lX25uX3RyMiRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNoaWNhZ29fY3JpbWVfbm5fdHIyJGRlc2NyaXB0aW9uKQpjaGljYWdvX2NyaW1lX25uX3RyMiRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubl90cjIkbG9jYXRpb25fZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIyJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90cjIkbG9jYXRpb25fZGVzY3JpcHRpb24pCmNoaWNhZ29fY3JpbWVfbm5fdHIyJG1vbnRoIDwtIGFzLm51bWVyaWMoY2hpY2Fnb19jcmltZV9ubl90cjIkbW9udGgpCmNoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGggPC0gYXMuZmFjdG9yKGNoaWNhZ29fY3JpbWVfbm5fdHIkbW9udGgpCgojU2NhbGluZyBvcmlnaW5hbCBkYXRhCnNldC5zZWVkKDcpCgojIGNyZWF0aW9uIG9mIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCmluZGV4IDwtIHNhbXBsZShucm93KGNoaWNhZ29fY3JpbWVfbm5fdHIyKSwgcm91bmQoMC43NSpucm93KGNoaWNhZ29fY3JpbWVfbm5fdHIyKSkpCnRyYWluIDwtIGNoaWNhZ29fY3JpbWVfbm5fdHIyW2luZGV4LF0KdGVzdCA8LSBjaGljYWdvX2NyaW1lX25uX3RyMlstaW5kZXgsXQoKdHJhaW4gPC0gYXMubWF0cml4KHRyYWluKQp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKdHJhaW5fbGFiZWw8LXRhcmdldF90cmFpbjJbaW5kZXhdCnRlc3RfbGFiZWw8LXRhcmdldF90cmFpbjJbLWluZGV4XQoKI21haW4gY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBtYXAKc29tX2dyaWQ8LXNvbWdyaWQoeGRpbT04LCB5ZGltPTgsIHRvcG89ImhleGFnb25hbCIpCgojdHJhaW5pbmcgdGhlIG1hcApjcmltZS5zb20gPC0gc29tKHRyYWluWzE6MTAwMDAwLF0sIGdyaWQ9c29tX2dyaWQsIAogICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgIHJhZGl1cz0gMiwga2VlcC5kYXRhPVQpCgojIE5hbWVzIG9mIHRoZSB2YXJpYWJsZXMgdXNlZApjb2xuYW1lcyh0cmFpbikKCiMgbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzdW1tYXJ5KGNyaW1lLnNvbSkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjaGFuZ2VzIikKCiNub2RlIGNvdW50cwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY291bnRzIiwgbWFpbj0iRXhhbXBsZXMgcGVyIE5ldXJvbiIpCgojQ29kZXMvV2VpZ2h0IHZlY3RvcnMKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvZGVzIiwgbWFpbj0iUGF0dGVybnMgRGlzY292ZXJlZCIpCgpjb29sQmx1ZUhPdFJlZDwtZnVuY3Rpb24obiwgYWxwaGE9MSl7cmFpbmJvdyhuLGVuZD00LzYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT1hbHBoYSlbbjoxXX0KcGFyKG1mcm93PWMoMiwzKSkKcGxvdChjcmltZS5zb20sIHR5cGU9InByb3BlcnR5IiwgcHJvcGVydHk9Z2V0Q29kZXMoY3JpbWUuc29tLCAxKVssMV0sCiAgICAgbWFpbj1jb2xuYW1lcyhnZXRDb2RlcyhjcmltZS5zb20sIDEpKVsxXSwKICAgICBwYWxldHRlLm5hbWU9Y29vbEJsdWVIT3RSZWQpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJwcm9wZXJ0eSIsIHByb3BlcnR5PWdldENvZGVzKGNyaW1lLnNvbSwgMSlbLDJdLAogICAgIG1haW49Y29sbmFtZXMoZ2V0Q29kZXMoY3JpbWUuc29tLCAxKSlbMl0sCiAgICAgcGFsZXR0ZS5uYW1lPWNvb2xCbHVlSE90UmVkKQpwbG90KGNyaW1lLnNvbSwgdHlwZT0icHJvcGVydHkiLCBwcm9wZXJ0eT1nZXRDb2RlcyhjcmltZS5zb20sIDEpWywzXSwKICAgICBtYWluPWNvbG5hbWVzKGdldENvZGVzKGNyaW1lLnNvbSwgMSkpWzNdLAogICAgIHBhbGV0dGUubmFtZT1jb29sQmx1ZUhPdFJlZCkKCgojIEFsdGVybmF0aXZlIGVhc2llcgpjb29sQmx1ZUhvdFJlZDwtZnVuY3Rpb24obiwgYWxwaGE9MSl7cmFpbmJvdyhuLGVuZD00LzYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYT1hbHBoYSlbbjoxXX0KCmBgYApgYGB7cn0KI0NsdXN0ZXJpbmcgcGF0dGVybnMgaW4gdGhlIG1hcApsaWJyYXJ5KFJDb2xvckJyZXdlcikKZ3JvdXBzPC04CiNBcHBseWluZyBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyBmb3IgZ3JvdXBpbmcgcGF0dGVybnMKY3JpbWUuaGM9Y3V0cmVlKGhjbHVzdChkaXN0KGNyaW1lLnNvbSRjb2Rlc1tbMV1dKSksIGdyb3VwcykKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvZGVzIiwgYmdjb2wgPSBicmV3ZXIucGFsKGdyb3VwcywgbmFtZT0iWWxHbkJ1IilbY3JpbWUuaGNdLAogICAgIG1haW49ImNsdXN0ZXJpbmcgdGhlIHBhdHRlcm5zIGRpc2NvdmVyZWQiKQphZGQuY2x1c3Rlci5ib3VuZGFyaWVzKGNyaW1lLnNvbSxjcmltZS5oYykKYGBgCmBgYHtyfQojU2NhbGluZyBvcmlnaW5hbCBkYXRhCnNldC5zZWVkKDcpCgojbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzb21fZ3JpZDwtc29tZ3JpZCh4ZGltPTgsIHlkaW09OCwgdG9wbz0iaGV4YWdvbmFsIikKc2V0LnNlZWQoNykKa29obWFwIDwtIHh5Zih0cmFpblsxOjEwMDAwMCxdLCB0cmFpbl9sYWJlbFsxOjEwMDAwMF0sCiAgICAgICAgICAgICAgZ3JpZD1zb21fZ3JpZCwgCiAgICAgICAgICAgICAgcmxlbj0xMDAsIGFscGhhPWMoMC4wNSwgMC4wMSksIAogICAgICAgICAgICAgIHJhZGl1cz0gMiwga2VlcC5kYXRhPVQpCgojU2hvd2luZyB0aGUgdHJhaW5pbmcgcHJvY2VzcwpwbG90KGtvaG1hcCwgdHlwZT0iY2hhbmdlcyIpCgojU2hvd2luZyBkaXN0cmlidXRpb24gb2Ygd2luZSBsYWJlbHMgaW4gbmV1cm9ucwpwbG90KGtvaG1hcCwgdHlwZT0iY29kZXMiLCAgY29kZVJlbmRlcmluZyA9ICJsaW5lcyIsIHNoYXBlPSJzdHJhaWdodCIsCiAgICAgbWFpbj1jKCJDcmltZSIpKQoKcGxvdChrb2htYXAsIHR5cGU9ImNvZGVzIiwgIGNvZGVSZW5kZXJpbmcgPSAibGluZXMiLCBzaGFwZT0ic3RyYWlnaHQiLAogICAgIG1haW49YygiIHBhdHRlcm5zIikpCgojIFBsb3R0aW5nIGNsYXNzZXMgaW4gbmV1cm9ucwojcGxvdChrb2htYXAsIHR5cGU9Im1hcHBpbmciLCBsYWJlbHM9YXMubnVtZXJpYyh0cmFpbl9sYWJlbCkrMywKIyAgICAgY29sPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsIHBjaD00LCBtYWluPSJNYXAgb2YgY2xhc3NlcyIsIHBhbGV0dGUubmFtZSA9IHRlcnJhaW4uY29sb3JzKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRyYWluaW5nIGRhdGEKcHJpbnQoIlRSQUlOSU5HIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdF90cjwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRyYWluLCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZV90cjwtdGFibGUodHJhaW5fbGFiZWwsa29obWFwLnByZWRpY3RfdHIkcHJlZGljdGlvbnNbWzJdXSkKY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25fdGFibGVfdHIpCgojUHJlZGljdGlvbiB1c2luZyB0aGUgdGVzdCBkYXRhCnByaW50KCJURVNUIFBSRURJQ1RJT04iKQprb2htYXAucHJlZGljdDwtIHByZWRpY3Qoa29obWFwLCBuZXdkYXRhPXRlc3QsIHdoYXRtYXAgPSAxKQpwcmVkaWN0aW9uX3RhYmxlPC10YWJsZSh0ZXN0X2xhYmVsLGtvaG1hcC5wcmVkaWN0JHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlKQpgYGAKYGBge3J9CiMjIFJFREVTCm5hcmNvdGljc19ubiA8LSBzdWJzZXQobmFyY290aWNzX3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssZGF5LGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpsaWJyYXJ5KGtvaG9uZW4pICMgZm9yIGJ1aWxkaW5nIHRoZSBTT00gbWFwCmxpYnJhcnkoY2FyZXQpICAgICAjZm9yIGNvbmZ1c2lvbiBtYXRyaXgKCiNFeHRyYWN0aW5nIHRhcmdldCB2YXJpYWJsZQp0YXJnZXRfdHJhaW4gPC0gbmFyY290aWNzX25uJGRpc3RyaWN0Cm5hcmNvdGljc19ubiA8LSBzdWJzZXQobmFyY290aWNzX25uLCBzZWxlY3Q9LWMoZGlzdHJpY3QpKQoKbmFyY290aWNzX25uJGFycmVzdCA8LSBhcy5mYWN0b3IobmFyY290aWNzX25uJGFycmVzdCkKbmFyY290aWNzX25uJGFycmVzdCA8LSBhcy5udW1lcmljKG5hcmNvdGljc19ubiRhcnJlc3QpCm5hcmNvdGljc19ubiRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKG5hcmNvdGljc19ubiRwcmltYXJ5X3R5cGUpCm5hcmNvdGljc19ubiRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyhuYXJjb3RpY3Nfbm4kcHJpbWFyeV90eXBlKQojbmFyY290aWNzX25uJGRpc3RyaWN0IDwtIGFzLm51bWVyaWMobmFyY290aWNzX25uJGRpc3RyaWN0KQojY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCkKbmFyY290aWNzX25uJGRlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihuYXJjb3RpY3Nfbm4kZGVzY3JpcHRpb24pCm5hcmNvdGljc19ubiRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKG5hcmNvdGljc19ubiRkZXNjcmlwdGlvbikKbmFyY290aWNzX25uJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihuYXJjb3RpY3Nfbm4kbG9jYXRpb25fZGVzY3JpcHRpb24pCm5hcmNvdGljc19ubiRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKG5hcmNvdGljc19ubiRsb2NhdGlvbl9kZXNjcmlwdGlvbikKbmFyY290aWNzX25uJG1vbnRoIDwtIGFzLm51bWVyaWMobmFyY290aWNzX25uJG1vbnRoKQoKI1NjYWxpbmcgb3JpZ2luYWwgZGF0YQpzZXQuc2VlZCg3KQojdGFyZ2V0X3RyYWluLnNjPC1zY2FsZShjaGljYWdvX2NyaW1lX25uX3RyKQojdGFyZ2V0X3Rlc3Quc2M8LXNjYWxlKGNoaWNhZ29fY3JpbWVfbm4pCgojIGNyZWF0aW9uIG9mIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCmluZGV4IDwtIHNhbXBsZShucm93KG5hcmNvdGljc19ubiksIHJvdW5kKDAuNzUqbnJvdyhuYXJjb3RpY3Nfbm4pKSkKdHJhaW4gPC0gbmFyY290aWNzX25uW2luZGV4LF0KdGVzdCA8LSBuYXJjb3RpY3Nfbm5bLWluZGV4LF0KCiN0cmFpbiA8LSBjaGljYWdvX2NyaW1lX25uX3RyCnRyYWluIDwtIGFzLm1hdHJpeCh0cmFpbikKI3Rlc3QgPC0gY2hpY2Fnb19jcmltZV9ubgp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKI3RyYWluX2xhYmVsPC10YXJnZXRfdHJhaW4KI3Rlc3RfbGFiZWw8LXRhcmdldF90ZXN0CnRyYWluX2xhYmVsPC10YXJnZXRfdHJhaW5baW5kZXhdCnRlc3RfbGFiZWw8LXRhcmdldF90cmFpblstaW5kZXhdCgojbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzb21fZ3JpZDwtc29tZ3JpZCh4ZGltPTgsIHlkaW09OCwgdG9wbz0iaGV4YWdvbmFsIikKCiN0cmFpbmluZyB0aGUgbWFwCmNyaW1lLnNvbSA8LSBzb20odHJhaW4sIGdyaWQ9c29tX2dyaWQsIAogICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgIHJhZGl1cz0gMiwga2VlcC5kYXRhPVQpCgojIE5hbWVzIG9mIHRoZSB2YXJpYWJsZXMgdXNlZApjb2xuYW1lcyh0cmFpbikKCiMgbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzdW1tYXJ5KGNyaW1lLnNvbSkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjaGFuZ2VzIikKCiNub2RlIGNvdW50cwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY291bnRzIiwgbWFpbj0iRXhhbXBsZXMgcGVyIE5ldXJvbiIpCgojQ29kZXMvV2VpZ2h0IHZlY3RvcnMKcGxvdChjcmltZS5zb20sIHR5cGU9ImNvZGVzIiwgbWFpbj0iUGF0dGVybnMgRGlzY292ZXJlZCIpCgpgYGAKYGBge3J9CiNTY2FsaW5nIG9yaWdpbmFsIGRhdGEKc2V0LnNlZWQoNykKCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09OCwgeWRpbT04LCB0b3BvPSJoZXhhZ29uYWwiKQpzZXQuc2VlZCg3KQprb2htYXAgPC0geHlmKHRyYWluLCB0cmFpbl9sYWJlbCwKICAgICAgICAgICAgICBncmlkPXNvbV9ncmlkLCAKICAgICAgICAgICAgICBybGVuPTEwMCwgYWxwaGE9YygwLjA1LCAwLjAxKSwgCiAgICAgICAgICAgICAgcmFkaXVzPSAyLCBrZWVwLmRhdGE9VCkKCiNTaG93aW5nIHRoZSB0cmFpbmluZyBwcm9jZXNzCnBsb3Qoa29obWFwLCB0eXBlPSJjaGFuZ2VzIikKCiNTaG93aW5nIGRpc3RyaWJ1dGlvbiBvZiB3aW5lIGxhYmVscyBpbiBuZXVyb25zCnBsb3Qoa29obWFwLCB0eXBlPSJjb2RlcyIsICBjb2RlUmVuZGVyaW5nID0gImxpbmVzIiwgc2hhcGU9InN0cmFpZ2h0IiwKICAgICBtYWluPWMoIkNyaW1lIikpCgpwbG90KGtvaG1hcCwgdHlwZT0iY29kZXMiLCAgY29kZVJlbmRlcmluZyA9ICJsaW5lcyIsIHNoYXBlPSJzdHJhaWdodCIsCiAgICAgbWFpbj1jKCIgcGF0dGVybnMiKSkKCiNQcmVkaWN0aW9uIHVzaW5nIHRoZSB0cmFpbmluZyBkYXRhCnByaW50KCJUUkFJTklORyBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3RfdHI8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10cmFpbiwgd2hhdG1hcCA9IDEpCnByZWRpY3Rpb25fdGFibGVfdHI8LXRhYmxlKHRyYWluX2xhYmVsLGtvaG1hcC5wcmVkaWN0X3RyJHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlX3RyKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRlc3QgZGF0YQpwcmludCgiVEVTVCBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3Q8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10ZXN0LCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZTwtdGFibGUodGVzdF9sYWJlbCxrb2htYXAucHJlZGljdCRwcmVkaWN0aW9uc1tbMl1dKQpjb25mdXNpb25NYXRyaXgocHJlZGljdGlvbl90YWJsZSkKYGBgCmBgYHtyfQojIyBSRURFUwpjcmltZW4gPC0gc3Vic2V0KHdlYXBvbnNfdmlvbGF0aW9uX3RyLCBzZWxlY3Q9LWMoY2FzZV9udW1iZXIsYmxvY2ssZGF5LGxhdGl0dWRlLGxvbmdpdHVkZSkpCgpsaWJyYXJ5KGtvaG9uZW4pICMgZm9yIGJ1aWxkaW5nIHRoZSBTT00gbWFwCmxpYnJhcnkoY2FyZXQpICAgICAjZm9yIGNvbmZ1c2lvbiBtYXRyaXgKCiNFeHRyYWN0aW5nIHRhcmdldCB2YXJpYWJsZQp0YXJnZXRfdHJhaW4gPC0gY3JpbWVuJGRpc3RyaWN0CmNyaW1lbiA8LSBzdWJzZXQoY3JpbWVuLCBzZWxlY3Q9LWMoZGlzdHJpY3QpKQoKY3JpbWVuJGFycmVzdCA8LSBhcy5mYWN0b3IoY3JpbWVuJGFycmVzdCkKY3JpbWVuJGFycmVzdCA8LSBhcy5udW1lcmljKGNyaW1lbiRhcnJlc3QpCmNyaW1lbiRwcmltYXJ5X3R5cGUgPC0gYXMuZmFjdG9yKGNyaW1lbiRwcmltYXJ5X3R5cGUpCmNyaW1lbiRwcmltYXJ5X3R5cGUgPC0gYXMubnVtZXJpYyhjcmltZW4kcHJpbWFyeV90eXBlKQojbmFyY290aWNzX25uJGRpc3RyaWN0IDwtIGFzLm51bWVyaWMobmFyY290aWNzX25uJGRpc3RyaWN0KQojY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCA8LSBhcy5mYWN0b3IoY2hpY2Fnb19jcmltZV9ubiRkaXN0cmljdCkKY3JpbWVuJGRlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihjcmltZW4kZGVzY3JpcHRpb24pCmNyaW1lbiRkZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNyaW1lbiRkZXNjcmlwdGlvbikKY3JpbWVuJGxvY2F0aW9uX2Rlc2NyaXB0aW9uIDwtIGFzLmZhY3RvcihjcmltZW4kbG9jYXRpb25fZGVzY3JpcHRpb24pCmNyaW1lbiRsb2NhdGlvbl9kZXNjcmlwdGlvbiA8LSBhcy5udW1lcmljKGNyaW1lbiRsb2NhdGlvbl9kZXNjcmlwdGlvbikKY3JpbWVuJG1vbnRoIDwtIGFzLm51bWVyaWMoY3JpbWVuJG1vbnRoKQoKI1NjYWxpbmcgb3JpZ2luYWwgZGF0YQpzZXQuc2VlZCg3KQojdGFyZ2V0X3RyYWluLnNjPC1zY2FsZShjaGljYWdvX2NyaW1lX25uX3RyKQojdGFyZ2V0X3Rlc3Quc2M8LXNjYWxlKGNoaWNhZ29fY3JpbWVfbm4pCgojIGNyZWF0aW9uIG9mIHRyYWluaW5nIGFuZCB0ZXN0IGRhdGFzZXRzCmluZGV4IDwtIHNhbXBsZShucm93KGNyaW1lbiksIHJvdW5kKDAuNzUqbnJvdyhjcmltZW4pKSkKdHJhaW4gPC0gY3JpbWVuW2luZGV4LF0KdGVzdCA8LSBjcmltZW5bLWluZGV4LF0KCiN0cmFpbiA8LSBjaGljYWdvX2NyaW1lX25uX3RyCnRyYWluIDwtIGFzLm1hdHJpeCh0cmFpbikKI3Rlc3QgPC0gY2hpY2Fnb19jcmltZV9ubgp0ZXN0IDwtIGFzLm1hdHJpeCh0ZXN0KQoKI3RyYWluX2xhYmVsPC10YXJnZXRfdHJhaW4KI3Rlc3RfbGFiZWw8LXRhcmdldF90ZXN0CnRyYWluX2xhYmVsPC10YXJnZXRfdHJhaW5baW5kZXhdCnRlc3RfbGFiZWw8LXRhcmdldF90cmFpblstaW5kZXhdCgojbWFpbiBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG1hcApzb21fZ3JpZDwtc29tZ3JpZCh4ZGltPTEyLCB5ZGltPTEyLCB0b3BvPSJoZXhhZ29uYWwiKQoKI3RyYWluaW5nIHRoZSBtYXAKY3JpbWUuc29tIDwtIHNvbSh0cmFpbiwgZ3JpZD1zb21fZ3JpZCwgCiAgICAgICAgICAgICAgIHJsZW49MTAwLCBhbHBoYT1jKDAuMDUsIDAuMDEpLCAKICAgICAgICAgICAgICAgcmFkaXVzPSAyLCBrZWVwLmRhdGE9VCkKCiMgTmFtZXMgb2YgdGhlIHZhcmlhYmxlcyB1c2VkCmNvbG5hbWVzKHRyYWluKQoKIyBtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnN1bW1hcnkoY3JpbWUuc29tKQoKI1Nob3dpbmcgdGhlIHRyYWluaW5nIHByb2Nlc3MKcGxvdChjcmltZS5zb20sIHR5cGU9ImNoYW5nZXMiKQoKI25vZGUgY291bnRzCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb3VudHMiLCBtYWluPSJFeGFtcGxlcyBwZXIgTmV1cm9uIikKCiNDb2Rlcy9XZWlnaHQgdmVjdG9ycwpwbG90KGNyaW1lLnNvbSwgdHlwZT0iY29kZXMiLCBtYWluPSJQYXR0ZXJucyBEaXNjb3ZlcmVkIikKCiNTY2FsaW5nIG9yaWdpbmFsIGRhdGEKc2V0LnNlZWQoNykKCiNtYWluIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgbWFwCnNvbV9ncmlkPC1zb21ncmlkKHhkaW09MTIsIHlkaW09MTIsIHRvcG89ImhleGFnb25hbCIpCnNldC5zZWVkKDcpCmtvaG1hcCA8LSB4eWYodHJhaW4sIHRyYWluX2xhYmVsLAogICAgICAgICAgICAgIGdyaWQ9c29tX2dyaWQsIAogICAgICAgICAgICAgIHJsZW49MTAwLCBhbHBoYT1jKDAuMDUsIDAuMDEpLCAKICAgICAgICAgICAgICByYWRpdXM9IDIsIGtlZXAuZGF0YT1UKQoKI1Nob3dpbmcgdGhlIHRyYWluaW5nIHByb2Nlc3MKcGxvdChrb2htYXAsIHR5cGU9ImNoYW5nZXMiKQoKI1Nob3dpbmcgZGlzdHJpYnV0aW9uIG9mIHdpbmUgbGFiZWxzIGluIG5ldXJvbnMKcGxvdChrb2htYXAsIHR5cGU9ImNvZGVzIiwgIGNvZGVSZW5kZXJpbmcgPSAibGluZXMiLCBzaGFwZT0ic3RyYWlnaHQiLAogICAgIG1haW49YygiQ3JpbWUiKSkKCnBsb3Qoa29obWFwLCB0eXBlPSJjb2RlcyIsICBjb2RlUmVuZGVyaW5nID0gImxpbmVzIiwgc2hhcGU9InN0cmFpZ2h0IiwKICAgICBtYWluPWMoIiBwYXR0ZXJucyIpKQoKIyBQbG90dGluZyBjbGFzc2VzIGluIG5ldXJvbnMKI3Bsb3Qoa29obWFwLCB0eXBlPSJtYXBwaW5nIiwgbGFiZWxzPWFzLm51bWVyaWModHJhaW5fbGFiZWwpKzMsCiMgICAgIGNvbD1hcy5udW1lcmljKHRyYWluX2xhYmVsKSszLCBwY2g9NCwgbWFpbj0iTWFwIG9mIGNsYXNzZXMiLCBwYWxldHRlLm5hbWUgPSB0ZXJyYWluLmNvbG9ycykKCiNQcmVkaWN0aW9uIHVzaW5nIHRoZSB0cmFpbmluZyBkYXRhCnByaW50KCJUUkFJTklORyBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3RfdHI8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10cmFpbiwgd2hhdG1hcCA9IDEpCnByZWRpY3Rpb25fdGFibGVfdHI8LXRhYmxlKHRyYWluX2xhYmVsLGtvaG1hcC5wcmVkaWN0X3RyJHByZWRpY3Rpb25zW1syXV0pCmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9uX3RhYmxlX3RyKQoKI1ByZWRpY3Rpb24gdXNpbmcgdGhlIHRlc3QgZGF0YQpwcmludCgiVEVTVCBQUkVESUNUSU9OIikKa29obWFwLnByZWRpY3Q8LSBwcmVkaWN0KGtvaG1hcCwgbmV3ZGF0YT10ZXN0LCB3aGF0bWFwID0gMSkKcHJlZGljdGlvbl90YWJsZTwtdGFibGUodGVzdF9sYWJlbCxrb2htYXAucHJlZGljdCRwcmVkaWN0aW9uc1tbMl1dKQpjb25mdXNpb25NYXRyaXgocHJlZGljdGlvbl90YWJsZSkKYGBgCmBgYHtyfQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKZ3JvdXBzPC0yMwojQXBwbHlpbmcgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgZm9yIGdyb3VwaW5nIHBhdHRlcm5zCmNyaW1lLmhjPWN1dHJlZShoY2x1c3QoZGlzdChjcmltZS5zb20kY29kZXNbWzFdXSkpLCBncm91cHMpCnBsb3QoY3JpbWUuc29tLCB0eXBlPSJjb2RlcyIsIGJnY29sID0gaGVhdC5jb2xvcnMoZ3JvdXBzKVtjcmltZS5oY10sCiAgICAgbWFpbj0iY2x1c3RlcmluZyB0aGUgcGF0dGVybnMgZGlzY292ZXJlZCIpCmFkZC5jbHVzdGVyLmJvdW5kYXJpZXMoY3JpbWUuc29tLGNyaW1lLmhjKQpgYGAKCgoK